Java~线程通信:等待/通知机制、等待通知的经典范式、管道输入输出流、Thread.join使用

本文详细介绍了Java中的volatile关键字和synchronized同步机制,以及基于对象的等待/通知经典范式。volatile确保线程间变量可见性,而synchronized保证线程安全。此外,还讲解了Piped流用于线程间数据传递以及Thread.join方法用于线程间的协作执行。
摘要由CSDN通过智能技术生成

volatile和synchronized关键字
  • Java支持多线程来访问一个对象或对象的成员变量
  • 但由于每个线程都有一份这个对象的拷贝,所以程序执行时,每个线程看到的变量不一定是最新的(对象和成员变量虽然放在共享内存中,但是多核处理器为了加快程序的执行,允许每个线程有一份自己的拷贝)
  • volatile关键字要求每一个线程对变量的访问和修改都在共享内存中,即每一次修改,所有的线程都可以看到
  • 过多的使用volatile会降低程序效率,偶尔一用可以
  • synchronized以修饰方法或者同步代码块的形式使用
  • synchronized可以保证同一时刻,只有一个线程在执行同步方法或者同步代码块,有效保证了线程安全
  • 无论是同步方法还是同步代码块,实现原理都是对监视器(monitor)的获取
  • 线程获取锁,先执行monitorenter(监视器进入)指令,执行成功就是获取锁成功.释放锁时需要执行monitorexit(监视器退出)指令
  • 获取监视器的过程具有排他性,即同一时刻,只能一个线程能获取到synchronized对象的监视器
  • 线程只有先获取到synchronized对象监视器,才能进入到同步方法或同步代码块中,如果没有获取到,会在方法/块的入口处陷入阻塞状态
    在这里插入图片描述
等待/通知机制
  • 等待通知机制:A线程调用对象O的wait方法进入等待,B线程调用O的notify/notifyAll方法来通知线程A,线程A从等待状态退出,继续执行操作.两个线程通过对象O的交互过程就是等待通知机制
  • A线程修改对象的值,B线程察觉到了值的变化,进行了响应的操作。这个模式就是生产者消费者模式.前者是生产者,后者是消费者.这种模式有效的实现了代码解耦
  • 等待通知的相关方法,比如notify()norityAll()wait()方法被定义在Object中,任何一个Java对象都具有

在这里插入图片描述

等待/通知经典范式

等待线程(消费者):

synchronized(某对象){
    while( 不满足条件 ){
        对象.wait();
    } 
    //如果满足,开始处理
}

通知线程(生产者):

synchronized(对象){
      改变条件;
      对象.notifyAll();//或者notify()方法
}
管道输入输出流(Piped)
  • 专门读取线程数据
  • 字节流:PipedOutputStream、PipedInputStream
  • 字符流:PipedReader、PiedWriter
  • Piped流的使用必须先进行连接:调用connect()方法
 public static void main(String[] args) throws Exception{
        PipedWriter out=new PipedWriter();
        PipedReader in=new PipedReader();
        //将输入输出进行连接,否则抛出IO异常
        out.connect(in);
        Thread p=new Thread(new Print(in),"p1");
        p.start();
        int receive=0;
        while((receive=in.read())!=-1){
            out.write(receive);
        }
        out.close();
    }
    
    static class Print implements Runnable{
        private PipedReader in;
        public Print(PipedReader in){
            this.in=in;
        }
        public void run(){
            int receive=0;
              try{
                  while ((receive=in.read())!=-1){
                      System.out.println((char)receive);
                  }
              }catch (IOException e){
              }
        }
        
    }
Thread.join()
  • 线程A调用线程B的join方法:线程A等待线程B终止后再继续执行.
  • 超时等待join(long mills),给定时间内如果线程B没有终止,就不再等待
public static void main(String[] args) throws Exception{
        Thread pre=Thread.currentThread();
        for(int i=0;i<10;i++){
            //每个线程有前一个线程的引用,等待前一个线程终止,才能返回
            Thread thread=new Thread(new Domin(pre),String.valueOf(i));
            thread.start();
            pre=thread;
        }
        TimeUnit.SECONDS.sleep(5);
        System.out.println("线程"+Thread.currentThread().getName()+"终止");
    }
    static class Domin implements  Runnable{
        private Thread thread;
        public Domin(Thread thread){
            this.thread=thread;
        }
        @Override
        public void run(){
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("当前线程是"+Thread.currentThread().getName()+"终止");
        }
    }

结果:

线程main终止
当前线程是0终止
当前线程是1终止
当前线程是2终止
当前线程是3终止
当前线程是4终止
当前线程是5终止
当前线程是6终止
当前线程是7终止
当前线程是8终止
f当前线程是9终止
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值