基本内容是:有一个流水线(channel),流水线一端有客户线程client,另一端有工人线程worker,客户不断把新的任务(request)放入流水线,工人在另一头获得任务,并执行,客户和工人的数量可多可少,就这么简单
这个所谓的pattern初看好像似曾相识,就是一个thread pool嘛, 按通常的做法,request可以实现Runnable接口,把要做的事情放在run方法中,由worker去执行,具体实现时还要注意同步的问题
public class Request {
private final String name;
private final int number;
public Request(int number, String name) {
this.number = number;
this.name = name;
}
public void execute(){
System.out.println(Thread.currentThread().getName() + " execute " + this);
}
@Override
public String toString() {
return "request [ no. " + number +" name. "+name + "]";
}
}
public class Channel {
private LinkedList<Request> requests;
private static final int MAX_REQUEST = 100;
private List<WorkerThread> workerThreads;
private int workerCount;
private int count;
public Channel(int works) {
this.workerCount = works;
if(workerCount < 1){
throw new RuntimeException("works < 1");
}
this.workerThreads = new ArrayList<>();
requests = new LinkedList<>();
init();
}
private void init() {
//创建工人线程
IntStream.range(0,workerCount).forEach(i->{
WorkerThread workerThread = new WorkerThread("worker-"+i,this);
workerThreads.add(workerThread);
});
}
public synchronized void put(Request request) {
try {
while (count >= MAX_REQUEST) {
this.wait();
}
requests.addLast(request);
count++;
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized Request take(){
try {
while (count <= 0){
this.wait();
}
Request request = requests.removeFirst();
count--;
notifyAll();
return request;
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
public void startWork(){
workerThreads.stream().forEach(Thread::start);
}
}
public class WorkerThread extends Thread {
private final Channel channel;
public WorkerThread(String name, Channel channel) {
super(name);
this.channel = channel;
}
@Override
public void run() {
try {
while (true){
Request request = channel.take();
request.execute();
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 这是向channel中放半成品的线程
*/
public class TransformThread extends Thread {
private final Channel channel;
public TransformThread(String name, Channel channel) {
super(name);
this.channel = channel;
}
@Override
public void run() {
try {
for (int i = 0; true ; i ++){
channel.put(new Request(i,getName()));
sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Client {
public static void main(String[] args){
Channel chanel = new Channel(2);
chanel.startWork();
new TransformThread("Jame",chanel).start();
new TransformThread("Jack",chanel).start();
new TransformThread("Tome",chanel).start();
}
}