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 ...
随机推荐
- C++——代码运行过程详解
#include <iostream> using namespace std; ;//初始化的全局变量:保存在数据段 char *p1;//未初始化的全局变量:保存在BSS段 int m ...
- TTF字体基本知识及其在QT中的应用
字体类型 以Windows为例,有4种字体技术: Raster:光栅型,就是用位图来绘制字形(glyph),每个字都以位图形式保存 Vector:矢量型,就是用一系列直线的结束点来表示字形 TrueT ...
- 转载 二十篇java技术热文
转自微信公众号:java知音 1,详解java类的生命周期 2,Java反射最佳实践 3,Spring的IOC原理 4,Java并发编程:volatile关键字解析 5,Java Thread 总结 ...
- [C++] c Struct VS c++ Struct
c Struct c语言生命变量要加上struct c语言结构体内部不能有函数 C语言结构体没有共有,私有和继承
- python 全栈基础作业题
1.执行 Python 脚本的两种方式 1..直接使用PyCharm执行 2.python run.py 调用python 解释器来调用python脚本 2.简述位.字节的关系 数据存储是以“字节”( ...
- [模板]KMP字符串匹配
洛谷P3375 注意:两次过程大致相同,故要熟读熟记,切勿搞混 可以看看其他的教程:http://www.cnblogs.com/c-cloud/p/3224788.html 本来就不太熟,若是在记不 ...
- MQTT协议实现Eclipse Paho学习总结
MQTT协议实现Eclipse Paho学习总结 摘自:https://www.cnblogs.com/yfliufei/p/4383852.html 2015-04-01 14:57 by 辣椒酱, ...
- 有一个5ml 的瓶子 和3ml 的瓶子 和 很多水 现在 要取出4ml的水 请写出编程 多种解法
//TODO public class demo { public static void main(String[] args) { demo.ss(); demo.sss(); } public ...
- Redis安装及HA(High Availability)配置(转)
出处:http://www.cnblogs.com/morvenhuang/p/4184262.html Redis是一种内存数据库,以KEY-VALUE(即键值对)的形式存储数据.这篇文章主要介绍的 ...
- 网站配置新的YII2可运行版本
1. config 中的 gitignore 先将 -local 加入版本库 2. 将 runtime 目录添加写权限 3. 将web目录的asset 添加写的权限 4.