多线程之通讯技术

本文通过一个生动的茶馆场景,讲解了多线程间的通讯问题。原来程序中,沏茶师傅和品茶人线程同步出现问题,导致混乱。为解决这个问题,引入了wait和notify方法,通过共享对象的flag状态来协调生产者和消费者的动作,实现了线程间的有效通讯,避免了资源浪费和不协调的情况。
摘要由CSDN通过智能技术生成

今天就来讲讲多线程通讯技术,在说这个之前,我要生活中的场景让大家整明白,闲扯淡几句,博主毕业之后去了几座城市,每个城市都有每个城市文化底蕴,也有每个地方人们所喜爱的生活方式,比如有的城市人们爱刷火锅,这个城市火锅店也是非常查之多,有的地方酒鬼特别多,大街小巷的小酒馆馆无处不在,但博主还是喜欢那座爱喝茶的城市,品茶香,知茶趣;品人生,知人趣。今天我以美女上茶这个案列详解多线程通讯技术送给大家,如有不好之处,望指正。

 如上图所示,一个线程做写操作,一个线程做读操作。生产者生产一个,消费者消费一个。就相当于沏茶师傅沏好一杯茶,美女给端上来,让品茶客人喝。

 上茶美女

@Data
public class BeautyWorman {

    /**
     * 美女名字
     */
    public String name;
      
}

沏茶师傅:

/**
 * 茶师傅沏茶
 */
public class MakeTea implements Runnable{
    BeautyWorman beautyWorman;

    public MakeTea(BeautyWorman beautyWorman){
         this.beautyWorman =  beautyWorman;
     }

    /**
     *
     */
    @Override
    public void run() {
        int count = 0;
        while (true) {
            synchronized (beautyWorman) {
                System.out.println("茶水以沏好,该让美女轮流上了!!!!!!!");
                if (count == 0) {
                    beautyWorman.name = "苏小小";
                } else {
                    beautyWorman.name = "柳如是";
                }
                count = (count + 1) % 2;
            }
         }
       }
    }

  品茶人:

public class DrinkTea implements Runnable{

    BeautyWorman beautyWorman;

    public DrinkTea(BeautyWorman beautyWorman){
        this.beautyWorman =  beautyWorman;
    }

    @Override
    public void run() {
        while (true){
           synchronized (beautyWorman){
               System.out.println(beautyWorman.name+"大美人上的茶老香了,好喝好喝!!!!!");
           }
        }
    }
}



测试下:

   public static void main(String[] args) {
        BeautyWorman beautyWorman = new BeautyWorman();
        MakeTea makeTea = new MakeTea(beautyWorman);
        DrinkTea drinkTea = new DrinkTea(beautyWorman);
        new Thread(makeTea).start();
        new Thread(drinkTea).start();
    }

 

 程序打印结果很明显不是我想要的,我们想要的结果是生产者生产一个,消费者消费一个,也就是茶师傅沏好一杯茶,品茶人喝一杯,现在全乱套了,沏茶的一直在沏茶,喝茶的一直在喝茶。

那么如何解决了:java为我们提供了两个api  wait   notify;多个线程实现通讯。

Wait:会让当前的线程变为阻塞状态,放弃cpu执行权,同时会释放锁。必须要在同步代码块中使用,且必须要通过对象锁this.wait。

为什么wait需要释放锁:目的就是为了能够让生产者写数据,防止死锁。

  Notify:唤醒锁池阻塞的线程,从就绪到运行状态。

来:我们来改造上面的程序:

如果共享对象的flag值为false情况下,则只能写不能读;说明美女手里没茶,需要先让沏茶师傅沏好茶

如果共享对象的flag值为true的情况下,则只能读,不能写。说明美女手上有茶,可以让客人品茶

我们来改造下代码。

@Data
public class BeautyWorman {

    /**
     * 名字
     */
    public String name;

    /**
     * 美女手上是否有茶,默认是没茶的
     */
    public boolean flag = false;

}
/**
 * 茶师傅沏茶
 */
public class MakeTea implements Runnable{
    BeautyWorman beautyWorman;

    public MakeTea(BeautyWorman beautyWorman){
         this.beautyWorman =  beautyWorman;
     }

    /**
     *
     */
    @Override
    public void run() {
        int count = 0;
        while (true) {
            synchronized (beautyWorman) {
                if(beautyWorman.flag){
                    try {
                        beautyWorman.wait();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
                System.out.println("茶水以沏好,该让美女轮流上了!!!!!!!");
                if (count == 0) {
                    beautyWorman.name = "苏小小";
                } else {
                    beautyWorman.name = "柳如是";
                }
                count = (count + 1) % 2;
                beautyWorman.flag = true;
                beautyWorman.notify();;
            }
         }
       }
    }

public class DrinkTea implements Runnable{

    BeautyWorman beautyWorman;

    public DrinkTea(BeautyWorman beautyWorman){
        this.beautyWorman =  beautyWorman;
    }

    @Override
    public void run() {
        while (true){
           synchronized (beautyWorman){
               if(!beautyWorman.flag){
                   try {
                       beautyWorman.wait();
                   }catch (Exception e){
                       e.printStackTrace();
                   }
               }
               System.out.println(beautyWorman.name+"大美人上的茶老香了,好喝好喝!!!!!");
               beautyWorman.flag = false;
               beautyWorman.notify();
           }
        }
    }
}

打印下:

 漂亮!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值