多线程之间的交互

像在一个参数版本中,中断和虚假唤醒是可能的,并且该方法应该始终在循环中使用:

  synchronized (obj) {
         while (<condition does not hold>)
             obj.wait();
         ... // Perform action appropriate to condition
     } 

 不能使用if来判断,应该使用while。

在多线程中判断使用while

package cn.zh.juc1205;


class Aircondition {

    private int number = 0;

    public synchronized void increment() throws Exception {
        //判断
        while (number != 0) {
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"\t" +number);
        //通知
        this.notifyAll();
    }
    public  synchronized void decrement() throws Exception {
        //判断
        while (number == 0) {
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"\t" +number);
        //通知
        this.notifyAll();
    }
}
/**
 *题目:现在两个线程,可以操作初始值为零的一个变量,
 * 实现一个线程对该变量加1,一个线程对该变量减1,
 * 实现交替,来10轮,变量初始值为零
 * 1.高内聚低耦合前提下,线程操作资源类
 * 2.判断/干活/通知
 * 3.防止虚假唤醒
 */
public class ProdConsumerDemo04 {

    public static void main(String[] args) throws Exception {

        Aircondition aircondition = new Aircondition();

        new Thread(()->{
            for (int i = 1; i <= 10; i++) {
                try {
                    aircondition.increment();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        new Thread(()->{
            for (int i = 1; i <= 10; i++) {
                try {
                    aircondition.decrement();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
        new Thread(()->{
            for (int i = 1; i <= 10; i++) {
                try {
                    aircondition.increment();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"C").start();
        new Thread(()->{
            for (int i = 1; i <= 10; i++) {
                try {
                    aircondition.decrement();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"D").start();


    }
}
package cn.zh.juc1205;


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class ShareData {

    private int number = 1;//A:1 B:2 C:3定义标志位
    private Lock lock = new ReentrantLock();
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();


    public void print5() {
        lock.lock();
        try {
            //1.判断
            while (number != 1) {
                c1.await();
            }
            //2.打印五次
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            //3.通知 如何通知第二个
            number = 2;

            c2.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void print10() {
        lock.lock();
        try {
            //1.判断
            while (number != 2) {
                c2.await();
            }
            //2.打印五次
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            //3.通知 如何通知第二个
            number = 3;

            c3.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void print15() {
        lock.lock();
        try {
            //1.判断
            while (number != 3) {
                c3.await();
            }
            //2.打印五次
            for (int i = 0; i < 15; i++) {
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            //3.通知 如何通知第二个
            number = 1;

            c1.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


}

/**
 * 备注多线程之间按顺序调用 实现A->B->C
 * 三个线程启动,要求如下:
 * AA打印5次,BB打印10次,CC打印15次
 * 接着
 *  AA打印5次,BB打印10次,CC打印15次
 *
 */
public class ConditionDemo {

    public static void main(String[] args) {
        ShareData shareData = new ShareData();

        new Thread(()->{
            for (int i = 1;i <= 10; i++) {
                shareData.print5();
            }

        },"A").start();
        new Thread(()->{
            for (int i = 1;i <= 10; i++) {
                shareData.print10();
            }

        },"B").start();
        new Thread(()->{
            for (int i = 1;i <= 10; i++) {
                shareData.print15();
            }

        },"C").start();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43554997/article/details/101768128