JDK 1.5提供了多线程升级方案
将同步synchronized替换成了显示的Lock操作。可以实现唤醒、冻结指定的线程。

Lock接口
Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。
线程间通信Condition接口
Condition可以替代传统的线程间通信,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll()。该对象可以通过Lock锁进行获取。

传统线程的通信方式,Condition都可以实现。

注意,Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用newCondition()方法。
ReentrantLock类
Java.util.concurrent.lock 中的Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。

ReentrantLock 类实现了Lock ,它拥有与synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上。)

用法示例:

private Lock lock = new ReentrantLock();//定义多态ReentrantLock类对象
private Condition cond_pro = lock.newCondition();//Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用Lock对象的newCondition()方法。
private Condition cond_con = lock.newCondition();//一个lock可以有多个相关的condition

首先创建一个ReentrantLock类的多态对象,即建立一把锁。然后将这把锁与两个Condition对象关联。

实例:

import java.util.concurrent.locks.*;class ProducerConsumerDemo {public static void main(String[] args) {Resource r = new Resource();Producer pro = new Producer(r);//生产者对象Consumer con = new Consumer(r);//消费者对象Thread t1 = new Thread(pro);Thread t2 = new Thread(pro);Thread t3 = new Thread(con);Thread t4 = new Thread(con);t1.start();t2.start();t3.start();    t4.start();    }}class Resource{private String name;private int count = 1;private boolean flag = false;private Lock lock = new ReentrantLock();//定义一个实现Lock接口的ReentrantLock类对象private Condition cond_pro = lock.newCondition();//Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用Lock对象的newCondition()方法。private Condition cond_con = lock.newCondition();//一个lock可以有多个相关的conditionpublic  void set(String name) throws InterruptedException//生产方法//注意这里抛出await()方法异常声明,交给调用者处理{lock.lock();    //手动加同步锁try{  while (flag)    //if→while 此时若生产完一个以后唤醒了另一个生产者,则再次判断,避免了两个生产者同时生产cond_pro.await();       //冻结生产方法this.name = name+"____"+count++;System.out.println(Thread.currentThread().getName()+"_______"+"生产者"+this.name);flag = true;cond_con.signal(); //唤醒消费方法,利用了condition的signal()指定唤醒对象        }finally    //{lock.unlock();}}public  void out()throws InterruptedException{lock.lock();try{while (!flag)cond_con.await();System.out.println(Thread.currentThread().getName()+"______"+"消费者"+this.name);flag = false;cond_pro.signal();}finally    //释放锁必须得到执行{lock.unlock();}}}class Consumer implements Runnable{private Resource res;public Consumer(Resource res){this.res = res;}public void run(){while (true){try    //由于out()方法抛出了异常声明,这里必须捕获。{res.out();}catch (InterruptedException e){}}}}class Producer implements Runnable{private Resource res;public Producer(Resource res){this.res = res;                }public void run(){while (true){    try{res.set("+商品+");}catch (InterruptedException e){}}}}

执行上述代码,观察结果:

可以看到,多个线程同时生产、消费,由于指定唤醒互异线程,因此并不会引起错误。

Java基础学习——多线程(线程间通信-生产者消费者代码示例)相关推荐

  1. java 生产者消费者_Java多线程:线程间通信—生产者消费者模型

    一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是, 多个线程之间如何协作呢 ? 我们看一个 ...

  2. 多线程-线程间通信-多生产者多消费者示例

    1.多线程-线程间通信-多生产者多消费者问题 多生产者和多消费者.等待唤醒机制. 产生了两个问题: 1.出现了多次连续生产,未消费,或者一个商品被消费多次. 解决:必须要--------每一个被唤醒的 ...

  3. java基础学习-多线程笔记

    说说Java中实现多线程有几种方法 创建线程的常用三种方式: 1. 继承Thread类 2. 实现Runnable接口 3. 实现Callable接口( JDK1.5>= ) 4. 线程池方式创 ...

  4. java synoch 加锁_线程间通信 - HappyCowboy - 博客园

    线程之间需要一些协调通信,来共同完成一件任务.Java多线程中,线程之间通信最常用的两个方法是wait()与notify() 使用wait()与notify()实现线程间的通信,需注意: ①wait( ...

  5. 抖音最后一面,问我Java 是如何实现线程间通信的?

    线程之间到底使用什么沟通的呢?如何把数值变化传递给其他子线程? 来源:blog.csdn.net/lanxian837820149/article/details/101479004 MarkerHu ...

  6. 【转】Java里如何实现线程间通信

    正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点:thread.join(), object.w ...

  7. Java基础21 多线程线程两种实现方式 锁

    一.多线程的概念 1.程序 :一个固定逻辑与数据的集合 就称为程序 例如淘宝 贪吃蛇小游戏 2.CPU: 中央处理器 主要用于协调程序与硬件进行配置的工作 3.并发与并行 1.并发(高并发) 在同一个 ...

  8. linux高级编程基础系列:线程间通信

    线程间通信机制: 线程是一种轻量级的进程. 进程的通信机制主要包括无名管道.有名管道.消息队列.信号量.共享内存以及信号等.这些机制都是由linux内核来维护的,实现起来都比较复杂,而且占用大量的系统 ...

  9. java Thread学习(线程间协作)

    线程件协作 线程之间除了使用锁同步两个任务的行为外,还需要进行协作,例如任务A必须在B完成后才能执行. wait()和notify()/notifyAll() wait()会去等待外部信号,并且在等待 ...

最新文章

  1. debian下编译安装php5.2
  2. suse 启动oracle11g,SuSe10下Oracle11g文件系统模式安装及配置、网络配置与连接
  3. python3.5文档
  4. java.lang.NoClassDefFoundError: org/apache/commons/collections/map/LRUMap 解决方法
  5. 自动挡跑高速用S挡还是D挡? 回答
  6. bzoj 4131: 并行博弈(博弈)
  7. linux根目录9个g,linux根目录下5个主要的目录,及目录的功能
  8. HashMap的实现原理、JDK1.7和JDK1.8的对比以及死锁问题
  9. 关于公众号文章搜索,有两个小技巧
  10. VS2012使用 MSDN教程
  11. lisp成套电气设计_关于成套设计转电气设计问题?
  12. 网页唤起QQ临时会话
  13. Android 性能优化 (十一) 电量优化全解析 秒变大神
  14. 单片机超声波测距模块原理与源码解析
  15. MyBatisPuls入门案例
  16. 在单机上通过docker搭建redis集群试验
  17. 2022秋招前端面试题(一)(附答案)
  18. 【LeetCode】不含重复字符的最长子字符串
  19. Dell戴尔笔记本电脑G3 3579原装出厂Windows10系统恢复原厂oem系统
  20. 三极管的检测及其管脚的判别

热门文章

  1. linux svn命令
  2. discuz 删除系统自带的附件上传
  3. 微软:97%电子邮件属于垃圾邮件
  4. 好程序员大数据培训技术分享:Hadoop集群同步
  5. 《软件设计师》——计算机组成原理与体系结构
  6. IP-Address TextBox
  7. Java虚拟机参数,增加虚拟机最大内存,在/etc/profile增加如下: export JAVA_OPTS=-Xms9g -Xmx9g...
  8. linux下挂载nas存储异常处理
  9. php补充安装扩展支持
  10. awstats 安装