java多线程-线程间协作

大纲:

  1. wait、notify、notifyAll
  2. Condition
  3. 生产消费者

一、wait、notify、notifyAll

  1. wait、notify、notifyAll是Object的本地final方法。
  2. 在一个线程中调用object.wait()可以使当先线程阻塞并交出锁(object)。
  3. 既然obj.wait操作会交出锁,那必然在synchronized(obj)代码块内,且2个obj为统一对象。
  4. 使用obj.notify()能够唤醒任意一个等待obj锁的线程,obj.notifyAll()能够唤醒所有等待obj锁的线程。同样notify操作也必须在synchronized(obj)代码块内。
  5. 线程等待是锁对象的方法而不是线程的方法,试想在多个synchronized嵌套代码块内,调用wait()是不是应该指定释放哪一个锁对象。

二、Condition

  1. Condition接口依赖于Lock接口,可以通过lock.newCondition() 。
  2. wait,notify操作都是控制一个锁下面的线程。Condition可以将一个锁下面的线程分成多种情况分别控制。
  3. 调用Condition的await()和signal()方法也需要在lock()-unlock()代码块内。
  4. Condition接口的await对应Object的wait方法 ,signal对应notify方法 ,signalAll对应notifyAll方法 。
  5. 使用Condition也更加高效。
  6. void awaitUninterruptibly():不响应中断的await方法。
  7. long awaitNanos(long nanosTimeout) throws InterruptedException:await上增加超时响应,返回值=nanosTimeout-消耗时间。

三、生产消费者

生产者、消费者线程轮流执行,操作同一个资源。

消费者:

public class Comsumer implements Runnable {
    Resource resource;
    public Comsumer(Resource resource){
        this.resource = resource;
    }
    @Override
    public void run() {
        try {
            resource.comsume();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

生产者:

public class Producer implements Runnable {
    Resource resource;
    public Producer(Resource resource){
        this.resource = resource;
    }
    @Override
    public void run() {
        try {
            resource.produce();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

资源对象-wait,notify实现:

public class Resource {

    private int r = 0;
    private Object lock = new Object();
    private boolean produced = false;

    public  void produce() throws InterruptedException {
        synchronized(lock){
            while (true){
                while (produced){
                    lock.wait();
                }
                r++;
                System.out.println(Thread.currentThread().getName()+"线程成产1个,当前剩余:"+r);
                produced = true;
                lock.notifyAll();
            }
        }

    }

    public void comsume() throws InterruptedException {
        synchronized(lock){
            while (true){
                while (!produced){
                    lock.wait();
                }
                r--;
                System.out.println(Thread.currentThread().getName()+"线程消费1个,当前剩余:>>"+r);
                produced = false;
                lock.notifyAll();
            }
        }

    }
}

资源对象-condition实现:

public class Resource {

    private int r = 0;
    private boolean produced = false;
    Lock lock = new ReentrantLock();
    Condition proCondition = lock.newCondition();
    Condition comCondition = lock.newCondition();

    public  void produce() throws InterruptedException {
        lock.lock();
        try {
            while (true){
                while (produced){
                    proCondition.await();
                }
                r++;
                System.out.println(Thread.currentThread().getName()+"线程成产1个,当前剩余:"+r);
                produced = true;
                comCondition.signal();
            }
        }finally {
            lock.unlock();
        }

    }

    public void comsume() throws InterruptedException {
        lock.lock();
        try {
            while (true){
                while (!produced){
                    comCondition.await();
                }
                r--;
                System.out.println(Thread.currentThread().getName()+"线程消费1个,当前剩余:>>"+r);
                produced = false;
                proCondition.signal();
            }
        }finally {
            lock.unlock();
        }

    }
}

 测试类

class TestWait {
    public static void main(String[] args) {
        Resource r = new Resource();
        Producer producer = new Producer(r);
        Comsumer comsumer = new Comsumer(r);
        new Thread(producer).start();
        new Thread(producer).start();
        new Thread(producer).start();
        new Thread(comsumer).start();
        new Thread(comsumer).start();
        new Thread(comsumer).start();
    }
}
原文地址:https://www.cnblogs.com/liuboyuan/p/10368991.html