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. 温故而知新 C++ 数组与指针

    #include <stdio.h> using namespace std; int main(int argc, _TCHAR* argv[]) { ]; ] = {,,,}; &qu ...

  2. 【转】ListView与RadioButton组合——自定义单选列表

    原文网址:http://blog.csdn.net/checkin001/article/details/11519131 Android自带的RadioButton单选框只支持添加文字,我们自己写A ...

  3. Visual studio 能否定位打开文件在项目中的位置

    文件位置:http://zhidao.baidu.com/link?url=FmwuCXTR2ptnRfqr7xGGPrnoXaONDAWgvO6iP4Dn736DwL7hEZCwQqanJbE0di ...

  4. Post/Redirect/Get pattern | PRG 模式

    Post/Redirect/Get 是一种 web 开发设计模式,用于防止表单的重复提交. 默认情况,提交 Post 请求到服务器后,如果直接刷新浏览器,会重新在提交一次 Post 请求.在访问电商网 ...

  5. (转)Maven实战(四)生命周期

    1. 三套生命周期     Maven拥有三套相互独立的生命周期,它们分别为clean,default和site. 每个生命周期包含一些阶段,这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和 ...

  6. linux用户权限相关命令

    1.创建组 groupadd test     修改组 groupmod -n test2 test 将名字改为test2     删除组 groupdel test     查看组 groups r ...

  7. AfxMessageBox和MessageBox差别

    假设用MFC的话,请尽量使用afxmessagebox,由于这个全局的对话框最安全,也最方便.   可是在WIN32 SDK的情况下仅仅能使用MESSAGEBOX. MessageBox()是Win3 ...

  8. 初探swift语言的学习笔记四(类对象,函数)

    作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/29606137 转载请注明出处 假设认为文章对你有所帮助,请通过留言 ...

  9. 使用MFC读写Excel

    _Application m_ExlApp;   //组件服务器的各个classes     _Workbook m_ExlBook;     Workbooks m_ExlBooks;     _W ...

  10. RollPagerView的用法:

    RollPagerView的用法: /** * * @author smiling * @date 2016/10 */ Android Studio 导包: compile 'com.jude:ro ...