大家好,又见面了,我是你们的朋友全栈君。
2.1什么是线程通信以及实现步骤
线程间通信的模型有两种:共享内存和消息传递
线程通信其实就是 ,实现线程的交替工作,并传递信息
线程间的通信具体步骤:(涉及上中下部)
- 创建资源类,在资源类中船舰属性和操作方法
- 在资源类操作方法:判断、操作、通知
- 创建多个线程,调用资源类的操作方法
- 防止虚拟唤醒问题 (if 判读,只会判断一次)
2.2 synchronized案例
操作线程的时候,等待线程使用wait()
通知另外的线程操作用notify()、notifyAll()
假设有两个线程,该线程在执行过程中,判断值(不是该值等待,让其他线程抢),操作值,通知另外一个线程的调度
实现两个线程 对num 这个值操作,一个线程加1,一个线程减1,交替实现多次
//第一步 创建资源类,定义属性和操作方法
class Share {
//初始值
private int num = 0;
//+1的方法
public synchronized void incr() throws InterruptedException {
//第二步 判断 干活 通知
if(number != 0) { //判断number值是否是0,如果不是0,等待
this.wait(); //在哪里睡,就在哪里醒
}
//如果number值是0,就+1操作
number++;
System.out.println(Thread.currentThread().getName()+" :: "+num);
//通知其他线程
this.notifyAll(); //注意这里的通知是随机的,就是只能通知全部
}
//-1的方法
public synchronized void decr() throws InterruptedException {
//判断
if(number != 1) {
this.wait();
}
//干活
number--;
System.out.println(Thread.currentThread().getName()+" :: "+number);
//通知其他线程
this.notifyAll();
}
}
public class ThreadDemo1 {
//第三步 创建多个线程,调用资源类的操作方法
public static void main(String[] args) {
Share share = new Share();
//创建线程
new Thread(()->{
for (int i = 1; i <=10; i++) {
try {
share.incr(); //+1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"AA").start();
new Thread(()->{
for (int i = 1; i <=10; i++) {
try {
share.decr(); //-1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();
}
}
可以看到,这时,代码是交替进行的 一个 +1 一个线程 -1
但是我们考虑如果同时 ,分别两个线程做加减,那会怎么样呢?
虚假唤醒 : wait 是在哪里睡,在哪里被唤醒只做了一次判断 虚假唤醒 放在while if 判断,只 会判断一次 所以改为while ;循环判断,就会解决虚假唤醒;从而解决这个错误
2.3 Lock案例
使用lock先要创建锁的对象以及通知的对象
放置在资源类中
private Lock lock= new ReentrantLock(); //创建可重锁
private Condition condition= lock.newCondition();
//他能操作的对象
上锁 lock.lock();
解锁 lock.unlock();
以下都为 condition类:
唤醒所有等待的线程signalAll(),带上类名condition.signalAll();
唤醒一个等待线程signal(),带上类名,condition.signal();
造成当前线程在接到信号或者被中断之前一直处于等待状态await(),带上类名,condition.await();
Lock 实现的代码基本是相同的,注意上锁 和解锁 是自己手动 做的工作,最终都要在finally 解锁
如果不解锁,会影响下面以后的线程
class LShare{
//这是共享资源,注意锁的创建和使用,其他的和上面基本相同
private int num=0;
private Lock lock= new ReentrantLock(); //创建可重锁
private Condition condition= lock.newCondition();
//创建操作的方法
public void add (){
lock.lock(); //首先 手动上锁;
try { //判断,干活,通知
while (num!=0){
condition.await();
//它使用的是这个对象 调用方法 等待
}
num++;
System.out.println( Thread.currentThread().getName()+" 干活完成 :"+num);
condition.signalAll(); //这个通知方法
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); //最终不管出现什么错误,都会解锁
}
}
这就实现了线程间的通信,,即 他们能够根据 信息,完成交替的工作
下面就是学如何 定制通信?(交替进行线程,但是每个线程的 工作是改变的)
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/160492.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...