JavaSE进阶

15.5.3 例 题

使用两个线程打印 1-100. 线程1, 线程2 交替打印

 

class Communication implements Runnable {

    int i = 1;

 

    public void run() {

        while (true) {

            synchronized (this) {

                notify();

                if (i <= 100) {

                    System.out.println(Thread.currentThread().getName() + ":" + i++);

                } else

                    break;

                try {

                    wait();

                } catch (InterruptedException e) {

                }

            }

        }

    }

}

经典例题:生产者/消费者问题

  • 生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
  • 这里可能出现两个问题:
  • 生产者比消费者快时,消费者会漏掉一些数据没有取到。
  • 消费者比生产者快时,消费者会取相同的数据。

 

public class TestProduct {

    public static void main(String[] args) {

        Clerk clerk = new Clerk();

        Thread productorThread = new Thread(new Productor(clerk));

        Thread consumerThread = new Thread(new Consumer(clerk));

        productorThread.start();

        consumerThread.start();

    }

}

 

class Clerk { // 售货员

    private int product = 0;

 

    public synchronized void addProduct() {

        if (product >= 20) {

            try {

                wait();

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        } else {

            product++;

            System.out.println("生产者生产了第" + product + "个产品");

            notifyAll();

        }

    }

 

    public synchronized void getProduct() {

        if (this.product <= 0) {

            try {

                wait();

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        } else {

            System.out.println("消费者取走了第" + product + "个产品");

            product--;

            notifyAll();

        }

    }

}

 

class Productor implements Runnable { // 生产者

    Clerk clerk;

 

    public Productor(Clerk clerk) {

        this.clerk = clerk;

    }

 

    public void run() {

        System.out.println("生产者开始生产产品");

        while (true) {

            try {

                Thread.sleep((int) Math.random() * 1000);

            } catch (InterruptedException e) {

            }

            clerk.addProduct();

        }

    }

}

 

class Consumer implements Runnable { // 消费者

    Clerk clerk;

 

    public Consumer(Clerk clerk) {

        this.clerk = clerk;

    }

 

    public void run() {

        System.out.println("消费者开始取走产品");

        while (true) {

            try {

                Thread.sleep((int) Math.random() * 1000);

            } catch (InterruptedException e) {

            }

            clerk.getProduct();

        }

    }

}