JDK5以后为代码的同步提供了更加灵活的Lock+Condition模式,并且一个Lock可以绑定多个Condition对象

1.把原来的使用synchronized修饰或者封装的代码块用lock.lock()与lock.unlock()进行手动的锁获取与释放

//原来的同步方式
synchronized (obj) {
...
} //JDK5.0新增的同步方式
//lock.unlock();建议最好要放在finally 执行
try {
lock.lock();
...
} finally {
lock.unlock();
}

2.把原来线程之间的通讯方式由锁对线obj.wait()和obj.notify()改成了Condition对象的con.await()与con.signal()方法

如下用Lock的方式重写多生产者多消费者模式时,线程可以指定唤醒生产者或者消费者,这样拥有更高的效率与安全性

 
package jdk5lockDome;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* @author wpy
*
*/
public class ProducerConsumer {
public static void main(String[] args) {
Resource resource = new Resource(); Producer producer0 = new Producer(resource);
Producer producer1 = new Producer(resource); Consumer consumer2 = new Consumer(resource);
Consumer consumer3 = new Consumer(resource); Thread t0 = new Thread(producer0);
Thread t1 = new Thread(producer1);
Thread t2 = new Thread(consumer2);
Thread t3 = new Thread(consumer3); t0.start();
t1.start(); t2.start();
t3.start(); } } class Producer implements Runnable {
private Resource resource; public Producer(Resource resource) {
this.resource = resource;
} @Override
public void run() {
while (true) {
resource.set("资源");
}
}
} class Consumer implements Runnable {
private Resource resource; public Consumer(Resource resource) {
this.resource = resource;
} @Override
public void run() {
while (true) {
resource.out();
}
}
} class Resource {
private String name;
private int count = 1;
// 是否生成完毕
private boolean flag = false; /**
* 互斥锁(同时只有一个线程拥有锁)
*/
private Lock lock = new ReentrantLock();
private Condition producerCon = lock.newCondition();
private Condition consumerCon = lock.newCondition(); /**
* 生产方法
*
* @param name
*/
public void set(String name) {
try {
lock.lock();
String threadName = Thread.currentThread().getName();
while (flag) {
System.out.println(threadName + "进入等待状态");
producerCon.await();
}
System.out.println(threadName + "取得执行权"); this.name = name + count;
count++;
System.out.println("生产者:" + this.name);
flag = true;
consumerCon.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} /**
* 消费方法
*/
public void out() {
try {
lock.lock();
String threadName = Thread.currentThread().getName();
while (!flag) {
System.out.println(threadName + "进入等待状态");
consumerCon.await();
}
System.out.println(threadName + "取得执行权"); System.out.println("============消费者:" + name);
flag = false;
producerCon.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}

  

  

Java多线程Lock的更多相关文章

  1. java多线程Lock接口简介使用与synchronized对比 多线程下篇(三)

    前面的介绍中,对于显式锁的概念进行了简单介绍 显式锁的概念,是基于JDK层面的实现,是接口,通过这个接口可以实现同步访问 而不同于synchronized关键字,他是Java的内置特性,是基于JVM的 ...

  2. Java多线程——Lock&Condition

    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. package ...

  3. java多线程lock的使用

    看代码: package com.ming.thread.reentrantlock; import java.util.concurrent.locks.Lock; import java.util ...

  4. 玩转Java多线程(Lock.Condition的正确使用姿势)

    转载请标明博客的地址 本人博客和github账号,如果对你有帮助请在本人github项目AioSocket上点个star,激励作者对社区贡献 个人博客:https://www.cnblogs.com/ ...

  5. java多线程-Lock

    大纲: Lock接口 synchronized&Lock异同 一.Lock public interface Lock { void lock(); void lockInterruptibl ...

  6. Java多线程编程核心技术--Lock的使用(一)

    使用ReentrantLock类 在Java多线程中,可以使用synchronized关键字来实现线程之间的同步互斥,但在JDK1.5中新增加了ReentrantLock类也能达到同样的效果,并且在扩 ...

  7. Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock

    在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(Reentrant ...

  8. java多线程系列(四)---Lock的使用

    Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理 ...

  9. java多线程(五)-访问共享资源以及加锁机制(synchronized,lock,voliate)

    对于单线程的顺序编程而言,每次只做一件事情,其享有的资源不会产生什么冲突,但是对于多线程编程,这就是一个重要问题了,比如打印机的打印工作,如果两个线程都同时进行打印工作,那这就会产生混乱了.再比如说, ...

随机推荐

  1. 关于高德地图Android开发时地图只显示一次、第二次打开不定位的解决办法

    我按照高德官方Demo改的 第一次是可以定位的,如左图 第二次就不能定位了,如右图 在onDestory中把aMap置为空即可 aMap = null; 修改完如下图: 原理是第二次打开时aMap不为 ...

  2. 如何将解压版的tomcat设置为windows 服务启动

    在web服务器上通常需要是web容器随开机自动启动,恰好Tomcat可以作为服务启动,只要经过我们简单的配置,就可以将免安装版的Tomcat添加到系统服务中. 首先需要配置以下环境变量: JAVA_H ...

  3. PL/SQL 三个小例子

    /* SQL语句 员工集合:select to_char(hiredate,'yyyy') from emp --> 光标 --> 循环--> 退出条件:notfound 变量 co ...

  4. Jquery cookie操作示例,写入cookie,读取cookie,删除cookie

    <html> <head> <meta name="viewport" content="width=device-width" ...

  5. ELK日志收集分析系统配置

    ELK是日志收益与分析的利器. 1.elasticsearch集群搭建 略 2.logstash日志收集 我这里的实现分如下2步,中间用redis队列做缓冲,可以有效的避免es压力过大: 1.n个ag ...

  6. 数据库的优化(表优化和sql语句优化)

    在这里主要是分为表设计优化和sql语句优化两方面来实现. 首先的是表设计优化: 1.数据行的长度不要超过8020字节.如果是超过这个长度的话这条数据会占用两行,减低查询的效率. 2.能用数字类型就不要 ...

  7. GooglePlay - 排行榜及支付接入

    前言 Google Play应用商店在国外Android市场中地位基本与AppStore在IOS中的地位一致,为此考虑国外的应用时,Android首要考虑的是接入GooglePlay的排行榜等支持. ...

  8. [Python]Codecombat攻略之地牢Kithgard(1-22关)

    首页:https://cn.codecombat.com/play语言:Python 第一界面:地牢 Kithgard(22关) 时间:1-3小时 内容:语法.方法.参数.字符串.循环.变量等 网页: ...

  9. CSS之 float 属性

    特性: float的设计初衷仅仅是文字环绕效果  浮动具有破坏性,会使父容器高度塌陷  清除浮动方法: 1.脚底插入cleart:both 2.父元素BFC(IE8+)/haslayout(IE6/7 ...

  10. win10 uwp 读写XML

    UWP 对 读写 XML做了一些修改,但和之前 WPF 的方法没有大的区别. 我们先来说下什么是 XML , XML 其实是 树结构,可以表达复杂的结构,所以在定制要求高的.或其他方面如json 做不 ...