package com.geelou.test.thread;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
class MyRunnable4 implements Runnable{
public static String[] threadNames = null;
public static int totalCard; // 卡片总数
public static int totalSteps; // 最大执行次数
ReentrantLock lock;
private int curId = 1;
private int finishNum = 0;
private AtomicInteger ato;
Map<Integer,Condition> conditionMap; // 锁集合
public MyRunnable4(){
lock = new ReentrantLock();
ato = new AtomicInteger();
conditionMap = new HashMap<>();
for(int i=1;i<=totalCard;i++){
conditionMap.put(i, lock.newCondition());
}
}
@Override
public void run() {
int id = getInt("id");
if(id == 0){
id = ato.incrementAndGet();
setThreadData("id", id);
setThreadData("name", threadNames[id-1]);
setThreadData("step", 0);
}
try{
while(true){
String name = getString("name");
//System.out.println("线程"+name+"尝试获取锁");
lock.lock();
id = getInt("id");
if(curId!=id){
//System.out.println("线程"+name+"开始等待");
conditionMap.get(id).await();
}
int step = getInt("step");
if(step==totalSteps){
step ++;
setThreadData("step", step);
}else if(step>totalSteps){
if(curId<totalCard){
curId++;
}else{
curId=1;
}
finishNum++;
conditionMap.get(curId).signal();
lock.unlock();
break;
}else{
step ++;
setThreadData("step", step);
System.out.println(name +"走了"+step+"步");
}
if(curId<totalCard){
curId++;
}else{
curId=1;
}
//System.out.println("线程"+name+"通知下一个线程恢复执行,下一个是"+curId);
conditionMap.get(curId).signal();
lock.unlock();
//System.out.println("线程"+name+"释放锁");
}
}catch(Exception ex){
ex.printStackTrace();
}
if(finishNum== totalCard){
System.out.println("全部都走完了");
}
}
private static ThreadLocal<Map<String,Object>> threadLocal = new ThreadLocal<>();
public static void setThreadData(String key,Object value){
Map<String,Object> map = threadLocal.get();
if(map==null){
map = new HashMap<>();
}
map.put(key, value);
threadLocal.set(map);
}
public static Object getThreadData(String key){
Map<String,Object> map = threadLocal.get();
if(map==null){
return null;
}
return map.get(key);
}
public static int getInt(String key){
Object o = getThreadData(key);
if(o == null){
setThreadData(key,0);
return 0;
}
return (Integer)o;
}
public static String getString(String key){
Object o = getThreadData(key);
if(o == null){
setThreadData(key,"");
return "";
}
return (String)o;
}
}
public class Thread4 {
public static void main(String[] args) {
MyRunnable4.threadNames = new String[]{"1 李强","2 毕显","3 文强","4 忠海","5 彭帅"};
MyRunnable4.totalSteps = 7;
MyRunnable4.totalCard = MyRunnable4.threadNames.length;
MyRunnable4 runnable = new MyRunnable4();
for(int i =0;i<MyRunnable4.totalCard;i++){
new Thread(runnable).start();
}
}
}