以下的代码模拟了一个生产与消费的场景,一个票池,生产者不停的往里面放数据,消费则不停的取数据.

票池

class Pool{

    private List<Integer> pool = new ArrayList<Integer>();

    //添加元素

    public void add(int i){

        pool.add(new Integer(i));

    }

    //剪切元素

    public Integer cut(){

        if(!this.pool.isEmpty()){

            return pool.remove(0);

        }

        return new Integer(0);

    }

}

生产者

class Producer extends Thread{

    private Pool pool;

    public Producer(Pool pool){

        this.pool = pool;

    }

    @Override

    public void run() {

        int i = 1;

        while(true){

            pool.add(i);

            System.out.println("producor "+i);

            i ++;

            try {

                this.sleep(400);

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

    }

}

消费者

class Consumer extends Thread{

    private Pool pool;

    public Consumer(Pool pool){

        this.pool = pool;

    }

    @Override

    public void run() {

        while(true){

            int tmp = pool.cut();

            System.out.println("consumer " +tmp);

            try {

                this.sleep(500);

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

    }

}

public class ThreadDemo2 {

    public static void main(String[] args) {

        Pool pool = new Pool();

        Producer p = new Producer(pool);

        Consumer c = new Consumer(pool);

        p.start();

        c.start();

    }

}

----------------------------------------------------分割线--------------------------------------------------------

    考虑一下这种情况,现在想要为票池添加一个最大票数,在不超过最大票数的时候生产者才能放数据然后,当放满后通知消费者消费. 消费者在没有票的情况下等待,只有票池有票才能去消费 以下是实现的代码:

package Thread.Synchronized;

import java.util.ArrayList;

import java.util.List;

class Pool{

    final static int MAX = 10;

    private List<Integer> pool = new ArrayList<Integer>();

    //添加元素

    public void add(int i){

        pool.add(new Integer(i));

    }

    //剪切元素

    public Integer cut(){

        if(!this.pool.isEmpty()){

            return pool.remove(0);

        }

        return new Integer(0);

    }

    public int getPoolSize(){

        return this.pool.size();

    }

    public List getPool(){

        return this.pool;

    }

}

class Producer extends Thread{

    private Pool pool;

    public Producer(Pool pool){

        this.pool = pool;

    }

    @Override

    public void run() {

        int i = 1;

        while(true){

            synchronized (pool.getPool()) {

                if(pool.getPoolSize()<Pool.MAX){

                    pool.add(i);

                    System.out.println("producor "+i);

                    i ++;

                    pool.getPool().notify();

                    try {

                        this.sleep(500);

                    } catch (InterruptedException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                }else{

                    try {

                        pool.getPool().wait();

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                }

            }

        }

    }

}

class Consumer extends Thread{

    private Pool pool;

    public Consumer(Pool pool){

        this.pool = pool;

    }

    @Override

    public void run() {

        int i;

        while(true){

            synchronized (pool.getPool()) {

                //集合为空

                try {

                    if(pool.getPool().size() == 0){

                        pool.getPool().wait();

                    }else{

                        i = pool.cut();

                        System.out.println("consumer " + i);

                        pool.getPool().notify();

                        this.sleep(200);

                    }

                } catch (Exception e) {

                    // TODO: handle exception

                }

            }

        }

    }

}

public class ThreadDemo2 {

    public static void main(String[] args) {

        Pool pool = new Pool();

        Producer p = new Producer(pool);

        Consumer c = new Consumer(pool);

        p.start();

        c.start();

    }

}

将票池中的票数组最为监视器对象 所有线程的消费者和生产者都在注视着他的变化,生产者发现他满了就通知消费者,消费者取完票就通知生产者.


----------------------------------------------------分割线----------------------------------------------------------------

线程死锁

   现在有这么一种场景,生产者在完成生产,消费者在完成消费,也就是说他们自身的行为后通知等待队列里的元素 去操作票池. 假设票池最大的量为1,一个生产者,两个消费者, 按以下步骤执行:

    1.生产者生产一张票后发出通知后继续抢占CPU

    2.生产者发现票池满了,进入等待队列,但他发出的通知唤醒了消费者C1

    3.C1去消费了这张票后发出通知,继续抢占CPU

    4.C1发现票池空了,进入等但队列,但他发出的通知唤醒了消费者C2

    5.C2进入了去消费发现票池空了,没能取到票,所以没有发通知,直接进入了等待队列

    6.现在 一个生产者,两个消费者全都困在等待队列中 这就造成了线程死锁.