前提背景:多个并发线程共享同一个资源时,为防止这些共享资源可能出现的错误或数据不一致问题,提出了临界区的概念
临界区: 指一个用以访问共享资源的代码块,这个代码块在同一时间内只能允许一个线程访问
实现方式:synchronized 或 lock
synchronized 方式如下, User 给addMoney方法加上了synchronized , 相当于加了锁,后面同时起了3个线程,都调这个方法,因为设置了sleep 3 秒,可以看到 会有2个线程处于 BLOCKED 的状态,直到释放
package com.zyguo.thread; public class User {
private int money;
private int id; public User( int id ){
this.setId(id);
}
public int getMoney() {
return money;
} public synchronized int addMoney( int incrNum ){
this.money = this.money + incrNum;
try {
Thread.sleep( );
System.out.println("addMoney, currThread=" + Thread.currentThread() );
} catch (InterruptedException e) {
e.printStackTrace();
}
return this.money;
} public synchronized 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_synchronized {
public static void main(String[] args) {
final User u = new User();
int threadNum = 3;
final ThreadGroup tgroup = new ThreadGroup("test-threadgroup");
final ArrayList<Thread> tList = new ArrayList<>();
//定义10个线程
for( int i = ; i < threadNum; i++ ){
Thread t = new Thread( tgroup, new Runnable() {
@Override
public void run() {
u.addMoney();
}
} ,"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 > ) {
for (Thread thread : tList) {
System.out.println( thread + ",state=" + thread.getState() );
}
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
activeCount = tgroup.activeCount();
}
}
}); t.start(); } }
结果如下
start thread = Thread[test-thread-0,5,test-threadgroup]
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=BLOCKED
Thread[test-thread-2,5,test-threadgroup],state=BLOCKED
Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
Thread[test-thread-2,5,test-threadgroup],state=BLOCKED
Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
Thread[test-thread-2,5,test-threadgroup],state=BLOCKED
addMoney, currThread=Thread[test-thread-0,5,test-threadgroup]
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
addMoney, currThread=Thread[test-thread-2,5,test-threadgroup]
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-2,5,],state=TERMINATED
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-2,5,],state=TERMINATED
Thread[test-thread-0,5,],state=TERMINATED
Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
Thread[test-thread-2,5,],state=TERMINATED
addMoney, currThread=Thread[test-thread-1,5,test-threadgroup]