在多线程中,1.5版本之前,我们都使用同步代码块或者同步方法来解决线程安全问题

比如:

同步代码块

synchronized(锁对象){

功能代码;

}

同步方法

public synchronized void test(){

功能代码;

}

在1.5版本,在java的工具类包中,java.util.concurrent.locks 中,推出了最新的

解决线程安全的方法,就是Lock+Condition的方式,

那这两种方式之间的关系和区别是什么呢?

加入对于线程常见的生产者消费者模式,我们使用两种方式实现,来看看他们的区别:

第一种,使用synchronized

我们完成一个男人挣钱女人花的例子

需求是如果没钱,男人线程挣一次钱,等待,然后唤醒女人去花钱,花完钱,等待,唤醒

男人去挣钱,一直循环这个过程,将男人线程看做生产线程,女人线程看做消费线程。

代码如下:

//首先完成共享数据

class Person{

String name;

boolean isMoney=true;

//挣钱

public void zhengQian(){

synchronized(this){

while(!isMoney){

try{wait();}catch(Exception e){}

}

name=“男人”;

System.out.println(Thread.currentThread().getName()+name+"—挣钱—");

isMoney=!isMoney;

notifyAll();//叫醒所有

}

}

//花钱

public void huaQian(){

synchronized(this){

while(isMoney){

try{wait();}catch(Exception e){}

}

name=“women。。。。人”;

System.out.println(Thread.currentThread().getName()+name+"—花=========钱—");

isMoney=!isMoney;

notifyAll();//叫醒所有

}

}

}

//输入线程

class In implements Runnable{

Person p=null;

In(Person p){

this.p=p;

}

public void run(){

while(true){

p.zhengQian();

}

}

}

//输出线程

class Out implements Runnable{

Person p=null;

Out(Person p){

this.p=p;

}

public void run(){

while(true){

p.huaQian();

}

}

}

从代码中可以看出,对于同步代码块或者同步方法来说,都是以锁对象this来控制其锁定的代码的。

api中也告诉我们:

Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。

那使用Lock+Condition怎么来实现呢?

代码如下:

import java.util.concurrent.locks.*;

class Person{

String name;

boolean isMoney=true;

Lock lock=new ReentrantLock();

Condition in=lock.newCondition();

Condition out=lock.newCondition();

//挣钱

public void zhengQian(){

lock.lock();

try{

while(!isMoney){

try{in.wait();}catch(Exception e){}

}

name=“男人”;

System.out.println(Thread.currentThread().getName()+name+"—挣钱—");

isMoney=!isMoney;

out.signal();//叫醒对方

}finally{

lock.unlock();

}

}

//花钱

public void huaQian(){

lock.lock();

try{

while(!isMoney){

try{out.wait();}catch(Exception e){}

}

name=“women。。。。人”;

System.out.println(Thread.currentThread().getName()+name+"—花=========钱—");

isMoney=!isMoney;

in.signal();//叫醒对方

}finally{

lock.unlock();

}

}

}

对比发现,Lock+Condition的方式是使用Condition对象来具体操作现场的等待和唤醒的,

也就是对于生产线程有专属的生成线程的Condition对象,对消费线程有专属的消费线程的Condition

对象,当等待或者唤醒时可以精确的控制是哪方线程,同步代码块或者同步方法在唤醒时,不能精确的

唤醒对方,所以只能唤醒全部,这时候增加了线程的判断次数,明显,Lock+Condition是优于synchronized的方式的

接下来我们分析下Lock和Condition的关系

Lock的子类对象是来取代synchronized的,也就是锁,Condition只是锁的操作对象

取代的是以前的锁对象,都拥有等待和唤醒的方法,虽然名字不同,Condition主要是对锁的操作对象

进行分类,如下图:

上图中,一个Lock对象,创建出来三个Condition对象 x,y,z

也就是以后执行这个锁的线程将会被分成三类线程,比如如果执行x.await(),执行这段代码的

三个绿色线程将会进入等待状态,再比如z中三个红色线程都处于等待状态,如果执行z.signal(),将会唤醒执行z的三个红色线程中的某一个,这样代码就可以正常运行了。

蓝色线两侧分别表示两个Lock的子类对象,每一个lock的Condition之间可以互相操作,对于两个

锁之间的Condition,比如,x和Q,就没有直接的关系了

好了,这篇文章主要说明下Lock+Condition方式来取代synchronized,希望对大家有所帮助。

本文来自千锋教育,转载请注明出处。

Java培训教程之使用Lock取代synchronized相关推荐

  1. java培训教程分享:Java中怎样将数据对象序列化和反序列化?

    本期为大家介绍的java培训教程是关于"Java中怎样将数据对象序列化和反序列化?"的内容,相信大家都知道,程序在运行过程中,可能需要将一些数据永久地保存到磁盘上,而数据在Java ...

  2. java培训教程分享:Java编写软件代码自动提示功能

    本期的java培训教程分享主要是介绍的java编写软件代码的一个自动提示功能,很多零基础和初学java的同学们对这一块还不是很了解,Eclipse for android 实现代码自动提示智能提示功能 ...

  3. java培训教程分享:Java中用户如何自定义异常?

    我们在学习java技术的时候应该有了解过,在java中是定义了很多的异常类的,虽然这些大量异常类可以帮助我们描述编程时出现的大部分异常情况,但是在程序开发中有时可能需要描述程序中特有的异常情况,例如在 ...

  4. java培训教程:什么是匿名内部类?怎样创建匿名内部类?

    本期java教程要为大家分享的是关于java中的匿名内部类,相信很多同学在学java技术的时候有了解过,下面我们就来详细的看一下. java培训教程:什么是匿名内部类?怎样创建匿名内部类?匿名内部类是 ...

  5. Java培训教程:”==“和 equals 方法究竟有什么区别?

    在学习java技术过程中,我们会接触到一些变量值的相关知识,本期小编为大家介绍的教程就是关于"=="和 equals 方法究竟有什么区别?来看看下面的详细介绍. Java培训教程: ...

  6. java培训教程学校,大量教程

    判定一家武汉Java培训机构好不好,要看这4点作为中部大省,武汉不仅学校众多,武汉Java培训机构也不少.想要去判定一家Java培训机构好不好,靠不靠谱,对于初学者而言并不容易.下面小千整理了一些关于 ...

  7. Java培训教程之使用Jsoup实现简单的爬虫技术

    1.Jsoup简述 Java中支持的爬虫框架有很多,比如WebMagic.Spider.Jsoup等.今天我们使用Jsoup来实现一个简单的爬虫程序. Jsoup拥有十分方便的api来处理html文档 ...

  8. Java培训教程之对象的创建与使用

    本文小千分享Java面向对象中的对象创建与使用.类是对象的抽象,为对象定义了属性和行为,但类本身既不带任何数据,也不存在于内存空间中.而对象是类的一个具体存在,既拥有独立的内存空间,也存在独特的属性和 ...

  9. Java培训教程:Java中的位移运算符!

    学习Java本来就是一件日积月累的事情,或许你通过自学能掌握一些皮毛技术,通过系统学习学到Java的一些基本大面,但想要做到精通,还是需要自己技术的日积月累和工作经验的不断积累. 今天小千给大家分享的 ...

最新文章

  1. numpy中的一些常见函数
  2. Python剑指offer:分行从上到下打印二叉树
  3. AngularJS分层开发
  4. guice spring_Spring vs Guice:重要的一个关键区别
  5. 爬虫可视化点选配置工具之chrome插件简介
  6. C#3.0亮点 —— lambda表达式
  7. 移动警务通GIS应用系统建设方案
  8. 读李虹之《画法几何及机械制图》
  9. 吴闲云——煮酒探西游
  10. idea2019.2版本gradle 使用offline
  11. QT QMessageBox 按钮文字更改为中文
  12. shio世硕AI智慧指读学习机加入智能教育硬件新战场【无标题】
  13. weui UI库适用范围
  14. idea风格ui java_IDEA界面太丑??尝试一下这几个风格
  15. new ActionListener(){}
  16. Communication error with Jack server
  17. TI物料电子元器件芯片LM3402MM/NOPB
  18. 快乐地谈谈:关于RSA算法中求私钥d的欧几里得方法(辗转相除法)考试向的欸
  19. 【渝粤题库】国家开放大学2021春1704农村社会学(本)题目
  20. php+head+下载,CMSHead 开源的PHPCMS系统下载/CMSHead 开源的PHPCMS系统官方下载-太平洋下载中心...

热门文章

  1. NeurIPS 2018 | 腾讯AI Lab:可自适应于不同环境和任务的强化学习方法
  2. hdu4280 Island Transport 网络流最大流 Dinic算法高效模板
  3. 增大iphone音量技巧_原来苹果手机隐藏功能这么好用!调整这个设置,一键增大外放音量...
  4. 【SpringBoot集成ElasticSearch 01】2️⃣ 种方式的高级客户端 RestHighLevelClient 使用(依赖+配置+客户端API测试源码)
  5. Spring注释详解
  6. 计算机验证型数学实验报告,精心设计论文,关于精心设计数学实验培养学生数学能力相关参考文献资料-免费论文范文...
  7. html5 将资源存于客户端,HTML5离线应用与客户端存储的实现
  8. oracle 服务管理,管理 Oracle 内容服务类别
  9. redis三种架构:主从Cluster哨兵+整合Springboot访问redis
  10. Python基础day07 作业解析【文件操作(文件读写、文件夹操作)】