package com.test.sync;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Pools {
private static final long timeout = 100000; //请求过期时间ms
private static final long contentTimeout = 10; //内容过期时间ms
private static final long contentMaxSize = 1; //最大内容数,超过之后,启动过期检查
private static volatile Map<String, Content> resultMap = new ConcurrentHashMap<String, Content>(); //存放结果信息
private static volatile Map<String, Thread> requestMap = new ConcurrentHashMap<String, Thread>(); //存放请求信息
private static volatile boolean isStart = false; //标记线程启动
private static Pools pool = new Pools();
private static Thread mainThread; //主线程
private Pools(){
start();
}
public static Pools getInstance(){
return pool;
}
//获取回调值
public Object callback(String key) {
Object result = null;
try {
//放入请求队列
requestMap.put(key, Thread.currentThread());
restart();
//阻塞请求
synchronized (Thread.currentThread()) {
System.out.println("等待中。。。。" + Thread.currentThread().getId());
Thread.currentThread().wait(timeout);
}
System.out.println("已唤醒。。。。" + Thread.currentThread().getId());
result = resultMap.get(key) == null ? null : resultMap.get(key).getObj();
resultMap.remove(key);
requestMap.remove(key);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
//将结果加入结果队列
public void put(String key, Object value){
resultMap.put(key, new Content(value, System.currentTimeMillis()));
restart();
}
//如果主线程已经休眠或者停止,重新启动
private void restart(){
synchronized (mainThread) {
if("WAITING".equalsIgnoreCase(mainThread.getState().name()) && !requestMap.isEmpty()&& !resultMap.isEmpty()){
System.out.println("notify");
mainThread.notify();
}else if("TERMINATED".equalsIgnoreCase(mainThread.getState().name())){
mainThread.run();
}
}
}
//启动循环监听
private synchronized void start(){
if(!isStart){
mainThread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
if(!resultMap.isEmpty() && !requestMap.isEmpty()){
String tmp;
//循环请求集,如果结果集中存在该结果,唤醒相应的等待线程
for(Iterator<String> it = requestMap.keySet().iterator(); it.hasNext(); ){
tmp = it.next();
System.out.println("check key-->" + tmp);
if(resultMap.containsKey(tmp)){
Thread t = requestMap.get(tmp);
synchronized(t){
t.notify();
}
}
}
//启动过期检查
if(resultMap.size() >= contentMaxSize){
for(Iterator<String> it = resultMap.keySet().iterator(); it.hasNext(); ){
tmp = it.next();
//判断是否超时
if(resultMap.get(tmp).isTimeout(contentTimeout)){
it.remove();
System.out.println("过期:" + tmp);
}
}
}
}else{
//如果队列为空,加大间隔
if(!"WAITING".equalsIgnoreCase(mainThread.getState().name())){
try {
synchronized (mainThread) {
mainThread.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
});
mainThread.start();
isStart = true;
System.out.println("-----------start------------");
}
}
class Content{
private Object obj; //内容
private long time; //创建时间
public Content(Object obj, long time){
this.setObj(obj);
this.time = time;
}
/**
* 检查内容是否过期
* @param t 过期时间t毫秒
* @return
*/
public boolean isTimeout(long t){
return System.currentTimeMillis() - time >= t;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
}
public static void main(String[] args) throws Exception {
for(int i=0; i<100; i++){
final int j = i;
new Thread(new Runnable() {
@Override
public void run() {
Pools.getInstance().put("k-" + j, true);
}
}).start();
}
System.out.println( Pools.getInstance().callback("k-20000"));
}
}
java 异步转同步工具类
最新推荐文章于 2022-05-09 11:22:08 发布