多线程09-Lock和Condition
1.概念
Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。
2.案例
package org.lkl.thread; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class LockFoo {
/**
* 两个线程打印姓名
*/ public static void main(String[] args) {
final Outputter out = new Outputter() ;
new Thread(new Runnable() { @Override
public void run() {
while(true){
try {
Thread.sleep() ;
out.print("zhangsan") ;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start(); new Thread(new Runnable() { @Override
public void run() {
while(true){
try {
Thread.sleep() ;
out.print("liaokailinliaokailinliaokailinliaokailinliaokailinliaokailin") ;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
} } class Outputter{
Lock lock = new ReentrantLock() ;
public void print(String name){
lock.lock() ; //加上锁 只有等到操作全完成以后才释放锁
try {
if(name!=null){
for(int i = ; i<name.length() ;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}finally {
lock.unlock() ;//解锁 一般都在finally中解锁 不过程序是否有异常 最终都要解锁 否则会导致阻塞
}
}
}
3. 读写锁
读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;
如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!
package cn.itcast.heima2; import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockTest {
public static void main(String[] args) {
final Queue3 q3 = new Queue3();
for(int i=;i<;i++)
{
new Thread(){
public void run(){
while(true){
q3.get();
}
} }.start(); new Thread(){
public void run(){
while(true){
q3.put(new Random().nextInt());
}
} }.start();
} }
} class Queue3{
private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
ReadWriteLock rwl = new ReentrantReadWriteLock();
public void get(){
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " be ready to read data!");
Thread.sleep((long)(Math.random()*));
System.out.println(Thread.currentThread().getName() + "have read data :" + data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwl.readLock().unlock();
}
} public void put(Object data){ rwl.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " be ready to write data!");
Thread.sleep((long)(Math.random()*));
this.data = data;
System.out.println(Thread.currentThread().getName() + " have write data: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwl.writeLock().unlock();
} }
}
4. Condition
package org.lkl.thead.foo01; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class ConditionFoo {
/**
* 子线程先执行10次 然后主线程再执行20次 如此循环50次
*/
public static void main(String[] args) {
final Business b = new Business() ;
//子线程执行50次
for(int i = ;i<= ;i++){
final int seq = i ;
new Thread(new Runnable() { public void run() {
b.sub(seq) ;
}
}).start() ;
} //主线程执行50次
for(int i = ;i<= ;i++){
b.main(i) ;
} } } class Business{
boolean isSub = true ; Lock lock = new ReentrantLock() ;
Condition condition = lock.newCondition() ;
//子线程执行10次
public void sub(int j ){ //加lock以后不需要synchronized
lock.lock() ;
try {
while(!isSub){
try {
condition.await() ;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i = ;i<= ;i++){
System.out.println("sub thread execute times " + i + " loop of "+ j);
} isSub = false ;
condition.signalAll() ;
} finally {
lock.unlock() ;
} } //主线程执行20次
public void main(int j ){
lock.lock() ;
try {
while(isSub){
try {
condition.await() ;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i = ;i<= ;i++){
System.out.println("main thread execute times " + i + " loop of "+ j);
} isSub = true ;
// condition.signal() ;
condition.signalAll() ;
}finally {
lock.unlock() ;
}
}
}
5. 通过condition实现三个线程之间的通信
package cn.itcast.heima2; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class ThreeConditionCommunication { /**
* @param args
*/
public static void main(String[] args) { final Business business = new Business();
new Thread(
new Runnable() { @Override
public void run() { for(int i=;i<=;i++){
business.sub2(i);
} }
}
).start(); new Thread(
new Runnable() { @Override
public void run() { for(int i=;i<=;i++){
business.sub3(i);
} }
}
).start(); for(int i=;i<=;i++){
business.main(i);
} } static class Business {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
private int shouldSub = ;
public void sub2(int i){
lock.lock();
try{
while(shouldSub != ){
try {
condition2.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=;j<=;j++){
System.out.println("sub2 thread sequence of " + j + ",loop of " + i);
}
shouldSub = ;
condition3.signal();
}finally{
lock.unlock();
}
} public void sub3(int i){
lock.lock();
try{
while(shouldSub != ){
try {
condition3.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=;j<=;j++){
System.out.println("sub3 thread sequence of " + j + ",loop of " + i);
}
shouldSub = ;
condition1.signal();
}finally{
lock.unlock();
}
} public void main(int i){
lock.lock();
try{
while(shouldSub != ){
try {
condition1.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=;j<=;j++){
System.out.println("main thread sequence of " + j + ",loop of " + i);
}
shouldSub = ;
condition2.signal();
}finally{
lock.unlock();
}
} }
}
多线程09-Lock和Condition的更多相关文章
- 多线程系列三:Lock和Condition
有了synchronized为什么还要Lock? 因为Lock和synchronized比较有如下优点 1. 尝试非阻塞地获取锁 2. 获取锁的过程可以被中断 3. 超时获取锁 Lock的标准用法 p ...
- python多线程锁lock/Rlock/BoundedSemaphore/Condition/Event
import time import threading lock = threading.RLock() n = 10 def task(arg): # 加锁,此区域的代码同一时刻只能有一个线程执行 ...
- java并发多线程显式锁Condition条件简介分析与监视器 多线程下篇(四)
Lock接口提供了方法Condition newCondition();用于获取对应锁的条件,可以在这个条件对象上调用监视器方法 可以理解为,原本借助于synchronized关键字以及锁对象,配备了 ...
- 并发之lock的condition接口
13.死磕Java并发-----J.U.C之Condition 12.Condition使用总结 11.Java并发编程系列之十七:Condition接口 === 13.死磕Java并发-----J. ...
- 四、线程同步之Lock和Condition
Lock同步锁 Lock 在jdk1.5 提供了Lock以便执行同步操作,和synchronized不同的是Lock提供了显示的方法获取锁和释放锁.Lock提供了以下几个方法,请求和释放锁: voi ...
- c#初学-多线程中lock用法的经典实例
本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义 lock 关键字可以用来确保代码块完成运行,而不会被 ...
- 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯
1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值 ...
- python多线程threading.Lock锁用法实例
本文实例讲述了python多线程threading.Lock锁的用法实例,分享给大家供大家参考.具体分析如下: python的锁可以独立提取出来 mutex = threading.Lock() #锁 ...
- 【Java线程】Lock、Condition
http://www.infoq.com/cn/articles/java-memory-model-5 深入理解Java内存模型(五)——锁 http://www.ibm.com/develope ...
- 【Java线程】锁机制:synchronized、Lock、Condition
http://www.infoq.com/cn/articles/java-memory-model-5 深入理解Java内存模型(五)——锁 http://www.ibm.com/develope ...
随机推荐
- LD1-K(求差值最小的生成树)
题目链接 /* *题目大意: *一个简单图,n个点,m条边; *要求一颗生成树,使得其最大边与最小边的差值是所有生成树中最小的,输出最小的那个差值; *算法分析: *枚举最小边,用kruskal求生成 ...
- library cache lock
SESSION 34 执行存储过程: SESSION 43 编译存储过程: SESSION 25 删除存储过程: 1.查询查看library cache lock等待事件的相关会话 SQL> s ...
- 【转】显示Ubuntu文件浏览器的地址栏--不错
原文网址:http://www.blogbus.com/anythingok-logs/144447448.html Ubuntu默认使用nautilus作为其可视化的文件浏览器,其默认值不显示地址栏 ...
- 【转】Android手机客户端关于二维码扫描的源码--不错
原文网址:https://github.com/SkillCollege/QrCodeScan QrCodeScan 这是Android手机客户端关于二维码扫描的源码,使用了高效的ZBar解码库,并修 ...
- 关于unsigned int和int的加法
补码(two's complement) 在计算机系统中,数值一律用补码来表示和存储.原因在于,使用补码,可以将符号位和数值域统一处理:同时,加法和减法也可以统一处理.此外,补码与原码相互转换,其运算 ...
- python:unittest(测试框架)
一,基本概念 TestCase:所有测试用例的基类 TestLoad:加载测试用例,返回TestSuite(测试套件) TestSuite:创建测试套件 TextTestRunner:运行测试用例 T ...
- SpringMVC 自定义拦截资料
1.springmvc学习笔记(28)——自定义拦截器 2.Spring MVC HandlerInterceptor Annotation Example with WebMvcConfigurer ...
- Oracle sqlplus 语法
目录: 0. FREFACE 1. 执行一个SQL脚本文件 2. 对当前的输入进行编辑 3. 重新运行上一次运行的sql语句 4. 将显示的内容输出到指定文件 5. 关闭spool输出 6.显示一个表 ...
- redis在Java web项目的简单应用(转载)
看到一篇关于redis和spring集成的文章,实际测试后,可以.转载以备用.谢谢 亲昵YY! html,body { font-size: 15px } body { font-family: He ...
- javascript 分离全局变量
当要编写一段javascript模块代码是, 这段代码将要在用在各种javascript程序中(就是各种各样的网页中), 为了让这段代码不与原来的代码起冲突,解决方法就是将代码放在一个函数(funct ...