多线程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 ...
随机推荐
- c# 接口代码实例
类和接口的实现 接口定义:为一组方法签名指定一个名称的方式. 类实现接口,就一定要提供接口所有方法的实现. 即使抽象类,也要全部实现,但是,它可以把接口方法声明为abstract的,从而把这个接口方法 ...
- VM虚拟机上 实现CentOS 6.X下部署LVS(DR)+keepalived实现高性能高可用负载均衡
一.简介 LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统.本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一. ...
- hdu 4550 卡片游戏
http://acm.hdu.edu.cn/showproblem.php?pid=4550 贪心 #include <cstdio> #include <cstring> # ...
- 【转】Android进阶2之Activity之间数据交流(onActivityResult的用法)----不错
原文网址:http://blog.csdn.net/sjf0115/article/details/7387467 主要功能: 在一个主界面(主Activity)上能连接往许多不同子功能模块(子Act ...
- Windows 不能在 本地计算机 启动 SQL Server 服务 错误代码126
本文转自:http://www.cnblogs.com/yuerdongni/archive/2012/08/18/2645140.html 在使用SQL2005(或2008)是可能会遇到错误提示: ...
- UVAlive4287 Proving Equivalences(scc)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=10294 [思路] 强连通分量. 求出bcc后,缩点形成DAG,设D ...
- [Java] 模板引擎 Velocity 随笔
Velocity 是一个基于 Java 的模板引擎. 本博文演示 Velocity 的 HelloWord 以及分支条件. HelloWord.vm,模板文件. templateDemo.java, ...
- C++ —— 非常量引用不能指向临时对象
目录 举例 分析 解决 1.举例 非常量引用 指向 临时对象 —— 即:将 临时对象 传递给 非常量引用类型. 如以下情况就会出现: 实现实数Rational类,实数可以使用+号相加,运算的结果要可以 ...
- Linux入门基础 #6:Linux用户基础
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
- 总结了关于PHP xss 和 SQL 注入的问题(转)
漏洞无非这么几类,XSS.sql注入.命令执行.上传漏洞.本地包含.远程包含.权限绕过.信息泄露.cookie伪造.CSRF(跨站请求)等.这些漏洞不仅仅是针对PHP语言的,本文只是简单介绍PHP如何 ...