多线程中的线程间通信及等待/通知机制的两种实现方式
来源:互联网 发布:凤岗数控车床编程培训 编辑:程序博客网 时间:2024/05/17 16:57
多线程编程中,如果每个线程之间互相独立,那么将会使多线程带来的优势不能够很好地发挥出来。使用线程间通信,可以使得原先的互相独立的多个线程之间,能够很好地互相协作,使得系统之间的交互性得到提升,大大提高了CPU利用率,从而完成一些复杂的多线程功能模块。 多线程间的通信一般采取等待/通知机制进行实现。见名知意,等待通知就是处于等待状态的线程需要由其他线程发出通知,从而可以再次获得CPU资源,执行之前没有执行完的任务。 Java中,常用的实现等待/通知机制的两种方式是: 一、在使用synchronized关键字实现的同步方法或同步代码块中,使用上锁的对象调用其自身的wait()方法和notify()方法以及notifyAll()方法,进行实现等待/通知机制; 二、在使用ReentrantLock类的对象实现的同步方法或同步代码块中,使用Contion类的对象的await()方法和signal()方法以及signalAll()方法,进行实现等待/通知机制; 在实现等待/通知机制之前,要注意以下事项: 一、wait()方法和notify()方法以及notifyAll()方法的使用必须在同步方法或者同步代码块中,因为这三个方法需要获得监视器对象的对象级别的锁;同样地,await()方法和signal()方法以及signalAll()方法的使用必须在其所属的Contion类的对象所关联的ReentrantLock类的对象(锁对象)所作用的方法或者代码块中; 二、wait()方法和await()方法的调用有两个作用:1、使当前线程由运行状态变为等待状态;2、释放当前线程持有的锁; 三、notify()方法和signal()方法的调用只有一个作用:唤醒因为wait()或await()而处于等待状态的线程;
synchronized同步中的等待/通知机制实现,示例代码:
package com.waitAndNotify; public class CommunicationInSynchronized { public static void main(String[] args) { String lock = "";//作为synchronized的对象监视器 CommunicationInSynchronized cis = new CommunicationInSynchronized ();//产生实例,用于创建内部类实例 Thread threadW = new Thread(cis.new ThreadW(lock));//实例化等待线程 threadW.setName("W");//给等待线程命名 threadW.start();//启动等待线程 Thread threadN = cis.new ThreadN(lock);//实例化通知线程 threadN.setName("N");//给通知线程命名 threadN.start();//启动通知线程 } //实现Runnable接口的等待线程类 class ThreadW implements Runnable{ private String lock; public ThreadW(String lock) { this.lock = lock; } @Override public void run() { synchronized(lock) { try { System.out.println( Thread.currentThread().getName() + " begin wait time:" + System.currentTimeMillis()); lock.wait();//当前线程进入等待队列,同时释放锁 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println( Thread.currentThread().getName() +" end wait time:" + System.currentTimeMillis()); } } } //通知线程类 class ThreadN extends Thread{ private String lock; public ThreadN(String lock) { this.lock = lock; } @Override public void run() { synchronized(lock) { try { System.out.println( Thread.currentThread().getName() + " begin notify time:" + System.currentTimeMillis()); lock.notify();//通知等待队列中的线程,使其进入就绪队列,等待获取锁 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " end notify time:" + System.currentTimeMillis()); } } } }
运行结果如下图所示:
ReentrantLock锁同步中的等待/通知机制实现,示例代码2:
package com.waitAndNotify; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class CommunicationInReentrantLock { public static void main(String[] args) { ReentrantLock lock = new ReentrantLock();//同步锁对象 Condition condition = lock.newCondition();//对应于同步锁对象的用于执行等待和通知命令的对象 CommunicationInReentrantLock cis = new CommunicationInReentrantLock ();//实例化对象,用于创建内部类的实例 Thread threadW = new Thread(cis.new ThreadW(lock,condition));//实例化等待线程 threadW.setName("W");//命名等待线程 threadW.start();//启动等待线程 Thread threadN = cis.new ThreadN(lock,condition);//实例化通知线程 threadN.setName("N");//命名通知线程 threadN.start();//启动通知线程 } //实现Runnable接口的等待线程类 class ThreadW implements Runnable{ private Lock lock; private Condition condition; public ThreadW(ReentrantLock lock,Condition condition) { this.lock = lock; this.condition = condition; } @Override public void run() { lock.lock();//上锁 try { System.out.println(Thread.currentThread().getName() + " begin wait time:" + System.currentTimeMillis()); condition.await();//使当前线程进入等待队列,同时释放当前持有的锁 System.out.println(Thread.currentThread().getName() + " end wait time:" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock();//释放锁 } } } //通知线程类 class ThreadN extends Thread{ private Lock lock; private Condition condition; public ThreadN(ReentrantLock lock,Condition condition) { this.lock = lock; this.condition = condition; } @Override public void run() { lock.lock();//上锁 try { System.out.println(Thread.currentThread().getName() + " begin notify time:" + System.currentTimeMillis()); condition.signal();//通知等待队列中的线程,使其进入就绪队列,准备获取锁 Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + " end notify time:" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock();//释放当前持有的锁 } } } }
运行结果如下图所示:
上述两个示例,实现了最基本的等待/通知机制,从两个示例的运行结果可以看出,两种方式实现结果完全一致,所以这两种方法都可以用于实现线程间的通信;但是线程间的通信较为复杂,实际应用中需要注意很多比较容易踩的"坑";因此,需要多积累,多实践。 通常开发过程中,等待/通知机制的经典案例就是生产者/消费者模式,生产者消费模式又分为单生产者单消费者模式、单生产者多消费者模式、多生产者单消费者模式以及多生产者多消费者模式;每一种模式中需要注意的点不同,可能会遇到线程的"假死"和因为等待条件的改变而导致的异常;这一部分将会在另一片博文进行阐述!
阅读全文
0 0
- 多线程中的线程间通信及等待/通知机制的两种实现方式
- java多线程之线程间通信:等待/通知机制
- java多线程的等待和通知机制,两种实现方法
- Java多线程之线程间通信--等待(wait)/通知(notify)机制,等待/通知之交叉备份实例
- 多线程 等待/通知机制的实现
- JAVA多线程-线程间通信(一)-等待/通知机制(wait/notify)
- Java多线程编程3--线程间通信--等待(wait)/通知(notify)机制
- java线程之间的通信(等待/通知机制)
- Java线程之间的通信-等待/通知机制
- java线程之间的通信(等待/通知机制)
- java线程之间的通信(等待/通知机制)
- java线程之间的通信(等待/通知机制)
- 多线程的等待/通知机制
- 利用等待唤醒机制实现线程间的通信
- 线程间的通信------------等待唤醒机制
- java线程等待/通知机制及中断
- Java多线程四:线程间通信/等待唤醒机制
- JavaSE 多线程 线程间通信— 等待唤醒机制
- 欧洲主要监管机构称ICO可能属于衍生品交易项目
- loading加载和layer.js
- 广播接收者
- 数据库与JavaBean字段名不一致处理
- [C/C++] 算法提高 5-3日历
- 多线程中的线程间通信及等待/通知机制的两种实现方式
- Oracle起步---创建临时表空间/表空间/创建用户/授权
- Angular 中修改bootstrap的模态框(modal)大小
- 新加坡央行公布“Project Ubin”第二阶段工作细节
- C# 内部类
- PAT乙级1060 爱丁顿数
- 巴西央行加速进行区块链研发
- 工作中常用的几个git命令
- HTML和CSS入门(6)