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的更多相关文章

  1. 多线程系列三:Lock和Condition

    有了synchronized为什么还要Lock? 因为Lock和synchronized比较有如下优点 1. 尝试非阻塞地获取锁 2. 获取锁的过程可以被中断 3. 超时获取锁 Lock的标准用法 p ...

  2. python多线程锁lock/Rlock/BoundedSemaphore/Condition/Event

    import time import threading lock = threading.RLock() n = 10 def task(arg): # 加锁,此区域的代码同一时刻只能有一个线程执行 ...

  3. java并发多线程显式锁Condition条件简介分析与监视器 多线程下篇(四)

    Lock接口提供了方法Condition newCondition();用于获取对应锁的条件,可以在这个条件对象上调用监视器方法 可以理解为,原本借助于synchronized关键字以及锁对象,配备了 ...

  4. 并发之lock的condition接口

    13.死磕Java并发-----J.U.C之Condition 12.Condition使用总结 11.Java并发编程系列之十七:Condition接口 === 13.死磕Java并发-----J. ...

  5. 四、线程同步之Lock和Condition

    Lock同步锁 Lock 在jdk1.5  提供了Lock以便执行同步操作,和synchronized不同的是Lock提供了显示的方法获取锁和释放锁.Lock提供了以下几个方法,请求和释放锁: voi ...

  6. c#初学-多线程中lock用法的经典实例

    本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义     lock 关键字可以用来确保代码块完成运行,而不会被 ...

  7. 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯

    1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值 ...

  8. python多线程threading.Lock锁用法实例

    本文实例讲述了python多线程threading.Lock锁的用法实例,分享给大家供大家参考.具体分析如下: python的锁可以独立提取出来 mutex = threading.Lock() #锁 ...

  9. 【Java线程】Lock、Condition

    http://www.infoq.com/cn/articles/java-memory-model-5  深入理解Java内存模型(五)——锁 http://www.ibm.com/develope ...

  10. 【Java线程】锁机制:synchronized、Lock、Condition

    http://www.infoq.com/cn/articles/java-memory-model-5  深入理解Java内存模型(五)——锁 http://www.ibm.com/develope ...

随机推荐

  1. .NET MVC执行过程

    1.网址路由比对 2.执行Controller与Action 3.执行View并返回结果 在使用MVC中是由IgnoreRoute()辅助方法对比成功的,会导致程序直接跳离MVC的执行生命周期,将程序 ...

  2. es watcher

    https://www.elastic.co/products/watcher https://www.elastic.co/blog/watcher-beta-goes-public-you-kno ...

  3. FLASK安装--兼收EZ_INSTALL及PIP

    参考URL: http://www.cnblogs.com/haython/p/3970426.html http://www.pythondoc.com/flask/installation.htm ...

  4. Android Broadcaset 简介

    在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制.而BroadcastReceiver是对发送出来的Broadcast进行过滤接收并响应的一类组件.可以使用Broad ...

  5. 关于group by【转载】

    1.概述 “Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理. 2.原始表 3.G ...

  6. adb Monkey用法

    以这条Monkey指令为例: #monkey -s --throttle -p com.android.cameraswitch -- 这条monkey指令是测试:在camera模块中产生1万次伪随机 ...

  7. 首届京东自有品牌科技周“京东点亮生活”圆满成功 - 课程公告板 - 京东内部论坛 - Powered by Discuz!

    首届京东自有品牌科技周"京东点亮生活"圆满成功 - 课程公告板 - 京东内部论坛 - Powered by Discuz! 首届京东自有品牌科技周"京东点亮生活" ...

  8. c# WinForm开发 DataGridView各种操作总结大全

    一.单元格内容的操作 //取得当前单元格内容 Console.WriteLine(DataGridView1.CurrentCell.Value); // 取得当前单元格的列 Index Consol ...

  9. Java中可变长参数的方法

    原文转自:http://www.cnblogs.com/lanxuezaipiao/p/3190673.html 在Java5 中提供了变长参数(varargs),也就是在方法定义中可以使用个数不确定 ...

  10. C primer plus 读书笔记第八章

    本章的标题是字符输入/输出和输入确认.主要内容是讨论用于I/O的标准函数. 1.getchar()和putchar() 这两个函数之前用过,我们通过这两个函数来讨论下缓冲区. #include &qu ...