5,临界区 之 lock
前提背景:多个并发线程共享同一个资源时,为防止这些共享资源可能出现的错误或数据不一致问题,提出了临界区的概念
临界区: 指一个用以访问共享资源的代码块,这个代码块在同一时间内只能允许一个线程访问
实现方式:synchronized 或 lock
lock 方式 如下 UserLock 给addMoney方法加上了 lock(), 相当于加了锁,后面同时起了3个线程,都调这个方法,因为设置了sleep 3 秒,可以看到 会有2个线程处于 WAITTING 的状态,直到锁释放
package com.zyguo.thread;
import java.util.concurrent.locks.ReentrantLock;
public class UserLock {
private int money;
private int id;
private ReentrantLock lock = new ReentrantLock();
public UserLock( int id ){
this.setId(id);
}
public int getMoney() {
return money;
}
public int addMoney( int incrNum ){
try {
lock.lock();
System.out.println("addMoney, lock=" + Thread.currentThread() + ",money=" + this.money );
this.money = this.money + incrNum;
Thread.sleep( 3000 );
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
lock.unlock();
System.out.println("addMoney, unlock=" + Thread.currentThread() + ",money=" + this.money );
}
return this.money;
}
public int reducMoney( int reducNum ){
this.money = this.money - reducNum;
return this.money;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package com.zyguo.thread;
import java.util.ArrayList;
public class Main_lock {
public static void main(String[] args) {
final UserLock u = new UserLock(1);
int threadNum = 3;
final ThreadGroup tgroup = new ThreadGroup("test-threadgroup");
final ArrayList<Thread> tList = new ArrayList<>();
//定义10个线程
for( int i = 0; i < threadNum; i++ ){
Thread t = new Thread( tgroup, new Runnable() {
@Override
public void run() {
u.addMoney(1);
}
} ,"test-thread-" + i);
tList.add( t );
t.start();
System.out.println("start thread = " + t );
}
//监控线程的活动的子线程数
Thread t = new Thread( new Runnable() {
@Override
public void run() {
int activeCount = tgroup.activeCount();
while ( activeCount > 0 ) {
for (Thread thread : tList) {
System.out.println( thread + ",state=" + thread.getState() );
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
activeCount = tgroup.activeCount();
}
}
});
t.start();
}
}
结果如下
start thread = Thread[test-thread-0,5,test-threadgroup]
addMoney, lock=Thread[test-thread-0,5,test-threadgroup],money=0
start thread = Thread[test-thread-1,5,test-threadgroup]
start thread = Thread[test-thread-2,5,test-threadgroup]
Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-1,5,test-threadgroup],state=WAITING
Thread[test-thread-2,5,test-threadgroup],state=WAITING
Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-1,5,test-threadgroup],state=WAITING
Thread[test-thread-2,5,test-threadgroup],state=WAITING
Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-1,5,test-threadgroup],state=WAITING
Thread[test-thread-2,5,test-threadgroup],state=WAITING
Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-1,5,test-threadgroup],state=WAITING
Thread[test-thread-2,5,test-threadgroup],state=WAITING
addMoney, lock=Thread[test-thread-1,5,test-threadgroup],money=1
addMoney, unlock=Thread[test-thread-0,5,test-threadgroup],money=2
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-2,5,test-threadgroup],state=WAITING
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-2,5,test-threadgroup],state=WAITING
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-2,5,test-threadgroup],state=WAITING
addMoney, unlock=Thread[test-thread-1,5,test-threadgroup],money=2
addMoney, lock=Thread[test-thread-2,5,test-threadgroup],money=2
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,],state=TERMINATED
Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,],state=TERMINATED
Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
addMoney, unlock=Thread[test-thread-2,5,test-threadgroup],money=3
5,临界区 之 lock的更多相关文章
- C#线程同步(1)- 临界区&Lock
文章原始出处 http://xxinside.blogbus.com/logs/46441956.html 预备知识:线程的相关概念和知识,有多线程编码的初步经验. 一个机会,索性把线程同步的问题在C ...
- [转]C#线程同步(1)- 临界区&Lock
第一印象,C#关于线程同步的东西好多,保持了C#一贯的大杂烩和四不象风格(Java/Delphi).临界区跟Java差不多只不过关键字用lock替代了synchronized,然后又用Moniter的 ...
- Lock同步锁--线程同步
Lock-同步锁 Lock是java5提供的一个强大的线程同步机制--通过显示定义同步锁对象来实现同步.Lock可以显示的加锁.解锁.每次只能有一个线程对lock对象加锁. Lock有ReadLock ...
- C#线程同步(2)- 临界区&Monitor
文章原始出处 http://xxinside.blogbus.com/logs/46740731.html 预备知识:C#线程同步(1)- 临界区&Lock 监视器(Monitor)的概念 可 ...
- 线程同步 – lock和Monitor
在多线程代码中,多个线程可能会访问一些公共的资源(变量.方法逻辑等等),这些公共资源称为临界区(共享区):临界区的资源是不安全,所以需要通过线程同步对多个访问临界区的线程进行控制. 同样,有些时候我们 ...
- Lock的await/singal 和 Object的wait/notify 的区别
在使用Lock之前,我们都使用Object 的wait和notify实现同步的.举例来说,一个producer和consumer,consumer发现没有东西了,等待,produer生成东西了,唤醒. ...
- 6,synchronized, lock 区别
参考文档 http://zzhonghe.iteye.com/blog/826162 http://houlinyan.iteye.com/blog/1112535 1,ReentrantLock 拥 ...
- 自旋锁Spin lock与互斥锁Mutex的区别
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API.线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用 ...
- Operating System-进程间互斥的方案-保证同一时间只有一个进程进入临界区(3)- TSL指令
本文接上一篇文章继续介绍如何实现同一时间只允许一个进程进入临界区的机制.本文主要介绍TSL指令. 方案汇总 屏蔽中断 锁变量 严格轮换法 TSL指令 Peterson解法 一.What is TSL ...
随机推荐
- Excel VBA 入门(零)
本教程所用系统环境: Windows 10 Excel 2013 1. 添加开发工具 打开Excel,依然找到"文件"->"选项"->"自 ...
- Codeforces 1154F (DP)
题意:有一个人去买铲子,他需要买正好k把.每把铲子有个标价,并且每把铲子最多只能被买一次.有m种优惠方案,每个优惠方案xi, yi是指如果这次恰好购买了xi把铲子,那么这次购买的铲子中最便宜的yi把将 ...
- android-tip-关于SurfaceView的使用
1. SurfaceView的创建和销毁 当SurfaceView隐藏时,SurfaceView被销毁,此时会调用SurfaceHolder.Callback.surfaceDestroyed ...
- Java 8特性
1. Java8的新特性 1.1. Lambda表达式和函数式接口 最简单的Lambda表达式可以用逗号分隔的参数列表.->符号和功能语句块来表示.示例如下: Arrays.asList( &q ...
- requests对象
属性 0.HttpRequest.scheme 表示请求方案的字符串(通常为http或https) 1.HttpRequest.body 一个字符串,代表请求报文的主体.在处理非 HTTP 形式的报文 ...
- Oracle RMAN-06023 和ORA-19693错误
在将一个0级备份的数据库还原到其它机器上时,首先遇到了RMAN-06023然后遇到ORA-19693错误,错误发生的环境和内容大致如下: 数据库版本: SQL> select * from v$ ...
- ACM暑假培训宣讲稿
(鞠躬)感谢大家的掌声! 我上台来作这次的宣讲,首先要感谢大家的捧场(当然,这是一句玩笑话),其实吧,我要感谢一下我们ACM班老大(班长),hjh队友,是他指派我来的,给了我这个宝贵的机会.最要感谢的 ...
- Perl 学习笔记-正则表达式处理文本
1.使用正则表达式替换文本 s/// s/<pattern>;/<replacement>;/ 如果匹配失败, 则什么也不会发生, 变量也不受影响. 返回布尔值, 替换成功 ...
- 认证服务号Thinkphp微信支付
公众号配置 1.微信支付过程中需要获取用户的openid,所以,仍需填写 网页授权域名 2.微信支付授权目录 Thinkphp目录格式为www.xxx.cn/home/wxpay/ 这里目录不能填写 ...
- a 标签 name 属性 页面定位 (二)
<a href="to_url#somewhere">名字</a> <a name="somewhere">名字</a ...