【详解】Java并发之确保挂起设计模式
分析
在Tomcat中的例子
Request -> Tomcat httpServer -> doing
.................
Request -> Tomcat httpServer -> Queue wait -> doing
需求
一个线程正在做一个非常关键的任务,这时,有一个其他的线程让当前线程做其他的事情,当前线程只有完成当前的任务才能做其他的任务。
解决方法
使用队列将其他需要工作的线程保存,然后在未来需要时,继续取队列中获取任务,然后执行。
public class ServerThread extends Thread {
private final RequestQueue queue;
private final Random random;
public ServerThread(RequestQueue queue) {
this.queue = queue;
random = new Random(System.currentTimeMillis());
}
@Override
public void run() {
while (!Thread.interrupted()){
Request request = queue.getRequest();
if (request == null){
break;
}
System.out.println("server ->"+request.getValue());
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
break;
}
}
}
}
public class RequestQueue {
private final LinkedList<Request> queue = new LinkedList<>();
/** * 放任务 * * @param request 请求任务 */
public void putRequest(Request request) {
synchronized (queue) {
queue.addLast(request);
queue.notifyAll();
}
}
/** * 取任务 * * @return */
public Request getRequest() {
synchronized (queue) {
while (!(queue.size() > 0)) {
try {
queue.wait();
} catch (InterruptedException e) {
return null;
}
}
if (Thread.interrupted()){
return null;
}
return queue.removeFirst();
}
}
}
public class Request {
final String value;
public Request(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
final RequestQueue queue = new RequestQueue();
new ClientThread(queue,"Alex").start();
ServerThread serverThread = new ServerThread(queue);
serverThread.start();
Thread.sleep(1000);
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
threadGroup.interrupt();
}
}