并行设计模式属于设计优化的一部分,它是对一些常用的多线程结构的总结和抽象。与串行程序相比,并行程序的结构通常更为复杂。因此,合理的使用并行模式在多线程开发中,更具有积极意义。并行程序设计模式主要有 Future模式 、Master-Worker模式、Guarded Suspension模式、不变模式和生产者-消费者模式,本文主要讲解 Future模式
Guarded Suspension意为暂停保护 该模式是一种保护模式,其核心是仅有服务可以提供服务的时候才提供服务
比如双十一期间,很多用户进行付账,客户端的请求数超过了服务器的即时处理能力,而服务端不能丢弃任何客户请求,此时最佳的方案就是让客户端的请求进行排队,服务端一个一个的处理。这样,既保证了所有的客户端请求不丢失,同时也避免了服务器由于同时处理太多的请求崩溃。此场景也和平时我们去银行办理业务类似,每次去就那么几个窗口,办理的客户太多了,那么能做的就是拿号排队。
核心代码如下:
角色 | 作用 |
---|---|
Request | 客户端请求 |
RequestQueue | 保护请求的队列 |
ClientThread | 客户端进程 |
ServerThread | 服务端进程 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class Request { private final String name; public Request(String name) { this .name = name; } public String getName() { return name; } public String toString() { return "[ Request " + name + " ]" ; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class RequestQueue { private final LinkedList queue = new LinkedList(); public synchronized Request getRequst() { while (queue.size() <= 0) { try { wait(); } catch (InterruptedException e) { // TODO: handle exception } } return (Request) queue.removeFirst(); } public synchronized void putRequest(Request requst) { queue.add(requst); notifyAll(); } } |
客户端进程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class ClientThread extends Thread { private Random random; private RequestQueue requestQueue; public ClientThread(RequestQueue requestQueue, String name, long seed) { super (name); this .requestQueue = requestQueue; this .random = new Random(seed); } public void run() { for (int i = 0; i < 10000; i++) { Request request = new Request( "No." + i); System.out.println(Thread.currentThread().getName() + " request " + request); requestQueue.putRequest(request); try { Thread.sleep(500); } catch (InterruptedException e) { } } } } |
服务端进程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class ServerThread extends Thread { private Random random; private RequestQueue requestQueue; public ServerThread(RequestQueue requestQueue, String name, long seed) { super (name); this .requestQueue = requestQueue; this .random = new Random(seed); } public void run() { for (int i = 0; i < 10000; i++) { Request request = requestQueue.getRequst(); System.out.println(Thread.currentThread().getName() + " handles " + request); try { Thread.sleep(1000); } catch (InterruptedException e) { } } } } |
1
2
3
4
5
6
7
8
9
10
|
public class Main { public static void main(String[] args) { RequestQueue requestQueue = new RequestQueue(); new ClientThread(requestQueue, "yuwei" , 3125467L).start(); new ServerThread(requestQueue, "xiaoxue" , 4265879L).start(); } } |
非常类似于NIO的channel