class common
{
    private char ch;
    private boolean available = false;
    synchronized char get()
    {
        while(available == false)
            try
            {
                wait();
            }catch(InterruptedException e)
            {}
            available = false;
            notify();
            return ch;
    }
    synchronized void put(char newch)
    {
        while(available == true)
        try{
            wait();
        }
        catch(InterruptedException e){}
        ch = newch;
        available = true;
        notify();
    }
}
class producer extends Thread
{
    private common comm;
    public producer(common thiscomm)
    {
        comm = thiscomm;
    }
    public void run()
    {
        char ch;
        for(ch='a';ch<='e';ch++)
        {
            System.out.println("生产的数据是:"+ch);
            comm.put(ch);
        }
    }
}class consumer extends Thread
{
    private common comm;
    public consumer(common thiscomm)
    {
        comm = thiscomm;
    }
    public void run()
    {
        char c;
        for(int i = 0;i<5;i++)
        {
            c = comm.get();
            System.out.println("消费者得到的数据是:"+c);
        }
    } 
    public static void main(String args[])
    {
        common comm = new common();
        producer p = new producer(comm);
        consumer c = new consumer(comm);
        p.start();
        c.start();
    }
}

解决方案 »

  1.   

        一个有限缓冲区和两类线程,它们是生产者和消费者,生产者把产品放入缓冲区,相反消费者便是从缓冲区中拿走产品。生产者在缓冲区满时必须等待,直到缓冲区有空间才继续生产。消费者在缓冲区空时必须等待,直到缓冲区中有产品才能继续读取。在这个问题上主要考虑的是:缓冲区满或缓冲区空以及竞争条件(race condition)。
      

  2.   

    这个代码还好象还有迷湖。
    就是两个synchronized的地方
      

  3.   

    同步跟多线程结合使用的一个关于生产者与消费者的问题1个生产者生产5个产品 'a'-'e'
    1个消费者消费产品1.生产者put 之后,消费者才能 get ,同一时刻只能有一个在操作2.有产品,生产者不 put3.无产品,消费者不 get
      

  4.   

    一个有限缓冲区和两类线程,它们是生产者和消费者,生产者把产品放入缓冲区,相反消费者便是从缓冲区中拿走产品。生产者在缓冲区满时必须等待,直到缓冲区有空间才继续生产。消费者在缓冲区空时必须等待,直到缓冲区中有产品才能继续读取。在这个问题上主要考虑的是:缓冲区满或缓冲区空以及竞争条件(race condition)。
      

  5.   

    class common
    {
        private char ch;
        private boolean available = false;//所谓的信号量
        synchronized char get()//同步的简写版,等效于:synchronized(this),即锁定当前对象。直接效果就是同样用synchronized修饰的方法之间“互斥”
        {
            while(available == false)//为了防止javaAPI上说的那个所谓虚假唤醒问题,所以必须加上这个检查。
                try
                {
                    wait();//等待时当前线程放弃自身持有的所有锁、进入等待队列,这是与sleep不同之处:sleep时线程仍然持有锁。
                }catch(InterruptedException e)
                {}
                available = false;
                notify();//任意挑一个处于等待队列的线程唤醒之,和用notifyAll差不多。注意wait()、notify()为Object的方法。sleep为Thread方法
                return ch;
        }
        synchronized void put(char newch)
        {
            while(available == true)
            try{
                wait();
            }
            catch(InterruptedException e){}
            ch = newch;
            available = true;
            notify();
        }
    }
    ...
    里面那个available的使用怎么这么别扭呢、没仔细看不一定对
      

  6.   

    class common
    {   //此类就相当生产者和消费者共同操作的一个和栈相似的类。
        //不过这个类只能装入一个字符就满啦~主要是有boolean来控制的
        private char ch;
        private boolean available = false;
        synchronized char get()//进行取出操作的时候;就行锁定。其他对象不可对他进行并发操作。
        {
            while(available == false)//当没有put的时候就会一直循环等待available变为true也就是栈中有字符的时候;
                try
                {
                    wait();//表示放弃当前线程拥有的对象锁。
                }catch(InterruptedException e)
                {}
                available = false;//取出之后就把available设置成FALSE;为了让栈能够装入
                notify();//让一个处于等待队列的线程唤醒之,拥有对象锁;
                return ch;
        }
        synchronized void put(char newch)//进行存入字符操作的时候;就行锁定。其他对象不可对他进行并发操作
        {
            while(available == true)//和取出操作一样都是进行判断是否为真假
            try{
                wait();
            }
            catch(InterruptedException e){}
            ch = newch;
            available = true;
            notify();
        }
    }
    class producer extends Thread
    {
        private common comm;//每个生产者都拥有一个可以存放字符的类;
        public producer(common thiscomm)
        {
            comm = thiscomm;//初始化
        }
        public void run()//继承了Thread类就会自动拥有此类
        {
            char ch;
            for(ch='a';ch<='e';ch++)
            {   //通过循环生产二十六个字母。
                 //不过每生产一个都会让消费者消费一个;因为所拥有的Common类的方法和属性所决定的
                System.out.println("生产的数据是:"+ch);
                comm.put(ch);
            }
        }
    }class consumer extends Thread
    {
        private common comm;
        public consumer(common thiscomm)
        {
            comm = thiscomm;
        }
        public void run()//生产者和消费者一样的道理
        {
            char c;
            for(int i = 0;i<5;i++)
            {   
                c = comm.get();
                System.out.println("消费者得到的数据是:"+c);
            }
        } 
        public static void main(String args[])
        {
            common comm = new common();//初始化一个类
            producer p = new producer(comm);
            consumer c = new consumer(comm);
            p.start();//自动执行生产者的run方法
            c.start();//自动执行消费者的run方法
        }
    }
      

  7.   

    学习一下,      wait();//表示放弃当前线程拥有的对象锁。
    这个看似是程序顺利运行的关键,
      

  8.   


    public class Sample07 {    /**
         * @param args
         */
        public static void main(String[] args) {
            Warehouse wh = new Warehouse();
            Product p1 = new Product(wh);
            Product p2 = new Product(wh);
            Consumer c = new Consumer(wh);        c.start();        try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }        p1.start();
            p2.start();
        }}class Product extends Thread {
        private Warehouse wh = null;    public Product(Warehouse wh) {
            this.wh = wh;
        }    public void run() {
            int num = 1;        while (num < 21) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                wh.push(num++);
            }
        }
    }class Consumer extends Thread {
        private Warehouse wh = null;    public Consumer(Warehouse wh) {
            this.wh = wh;
        }    public void run() {
            while (true) {            try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (wh.pop() == 20) {
                    break;
                }
            }
        }
    }class Warehouse {
        private int num = 0;    private boolean isFull = false;    public synchronized void push(int num) {
            if (!isFull) {
                this.num = num;
                System.out.println("生产者" + Thread.currentThread().getName() + "放入--->" + num);
                isFull = true;
                notify();
            }        if (isFull) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }    public synchronized int pop() {
            if (isFull) {
                System.out.println("消费者获得--->" + num);
                isFull = false;
                notifyAll();
                return num;
            }        if (!isFull) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return -1;
        }
    }
    public class Sample08 extends Thread {
        private Object o1 = null;
        
        private Object o2 = null;
        
        public Sample08(Object o1, Object o2) {
            this.o1 = o1;
            this.o2 = o2;
        }
        
        public void run() {
            synchronized (o1) {
                System.out.println(Thread.currentThread().getName() + "锁住对象" + o1);
                
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                synchronized (o2) {
                    System.out.println(Thread.currentThread().getName() + "锁住对象" + o2);
                }
                System.out.println(Thread.currentThread().getName() + "释放对象" + o2);
            }
            System.out.println(Thread.currentThread().getName() + "释放对象" + o1);
        }    /**
         * @param args
         */
        public static void main(String[] args) {
            String str1 = "str1";
            String str2 = "str2";
            String str3 = "str3";
            
            Sample08 t1 = new Sample08(str1, str2);
            Sample08 t2 = new Sample08(str2, str3);
            Sample08 t3 = new Sample08(str3, str1);
            
            t1.start();
            t2.start();
            t3.start();
        }}
    public class Sample09 {    /**
         * @param args
         */
        public static void main(String[] args) {
    //        ExecutorService es = Executors.newFixedThreadPool(3);
    //        ExecutorService es = Executors.newSingleThreadExecutor();
            ExecutorService es = Executors.newCachedThreadPool();        for (int i = 0; i < 1000; i++) {
                Task t = new Task();
                es.submit(t);
            }
            
            System.out.println("加载任务完成");
            es.shutdown();
            System.out.println("main is over");
        }
    }class Task implements Runnable {
        private String name = "";    private static int num = 1;
        
        private static int step = 0;    private long sleepTime = 200;    public Task(String name, long sleepTime) {
            this.name = name;
            this.sleepTime = sleepTime;
        }    public Task() {
            this("task-" + num, 200);
            num++;
        }    public void run() {
            int num = 1;
            int all = new Random().nextInt(20) + 1;
            System.out.println("\n==========" + Thread.currentThread().getName()
                    + "开始执行" + name + "任务(该任务有" + all + "步)" + "==========");
            step = 0;
            while (num <= all) {
                System.out.print("执行任务" + name + "第" + num++ + "步  ");
                step++;
                if (step % 6 == 0) {
                    System.out.println();
                }
                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("\n==========" + Thread.currentThread().getName()
                    + "执行完毕==========");
            step = 0;
        }
    }
      

  9.   

    建议楼主看下《Java多线程设计模式详解》,第5章,源代码与讲解都很详细。