java并发编程基础--线程通信的几种方式简单介绍与部分示例

一、使用wait,notify,notifyAll

1、使用场景:在多线程环境下,有时候一个线程的执行,依赖于另外一个线程的某种状态的改变,这个时候,我们就可以使用wait与notify或者notifyAll

2、注意点:

     1)wait与sleep的区别:wait会释放持有的锁,而sleep不会,sleep只是让线程在指定时间内休眠,不去抢占CPU的资源

     2)wait notify必须放在同步代码块中,且必须拥有当前对象的锁,即哪个对象wait,就调用哪个对象的notify

     3)notify随机唤醒一个等待的线程;而notifyAll唤醒所有在该对象上等待的线程

二、使用管道流方式

1、使用场景:以内存为媒介,用于线程间的数据传输。主要有面向字节:【PipedOutputStream、PipedInputStream】、面向字符【PipedReader、PipedWriter】

2、示例:创建两个类,分别为Main类和Reader类;Main类作为一个线程输入数据,Reader类作为线程读取主线程的数据

三、使用Thread.join通信

1、使用场景:线程A执行到一半,需要一个数据,这个数据需要线程B去执行修改,只有B修改完成之后,A才能继续操作线程A的run方法里面,调用线程B的join方法,这个时候,线程A会等待线程B运行完成之后,再接着运行

2、示例:先运行线程2,运行到一半开始运行线程1,等待线程1完成后继续运行线程2

四、使用 ThreadLocal

1、使用场景:线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储结构。每个线程单独存放一份变量副本

    一般用的比较多的是
        1、ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。
        2、ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。
        3、ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。
        4、ThreadLocal.initialValue: ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值。

2、示例:创建两个线程实现自增

由结果可以看出:只要线程处于活动状态并且ThreadLocal实例可访问,那么每个线程都拥有对其本地线程副本的隐式引用变量;一个线程消失后,它的所有副本线程局部实例受垃圾回收(除非其他存在对这些副本的引用)

五、使用Condition

1、使用场景:可以在一个锁里面,存在多种等待条件

2、singal()方法用于唤醒一个在等待中的线程。相对的singalAll()方法会唤醒所有在等待中的线程。这和方式一的Obejct.notify()方法类似。

condition.await()方法必须在lock.lock()与lock.unlock()方法之间调用。与Object.wait()方法类似


 

猜你喜欢

转载自blog.csdn.net/qq_38966361/article/details/87925310