1,从名字上看,工人线程可以联想到有一家工厂,里面有固定数量的工人,每个工人收到任务后都会独立开展工作,相互之间互不影响。每个工人就可以当作是一个独立的线程,由于工人的数量有固定的,所以线程的数量也是固定。
2,适用范围,该模式可以看作是一种线程池模式,一个工厂里面有多少个工人,这个是一个固定的数量,相当于在程序启动的时候先建立好固定数量的线程,然后这些线程不断的处理来自四面八方发送到该工厂的请求。
3,实现方式,这里有4个概念,第一是Request,可以把看作是生产需求,第二是Client,可以把他看作是客户,客户发送生产需求,一个工厂可以接收来自多个客户的需求,每个客户都可以看作是一个独立的线程。第三是Channel,生产线,一条生产线接受不同客户发过来的需求。第四是Worker,工人,一条生产线在组建的时候就已经安排好固定数量的工人,每个工人可以看作是一条独立的线程,生产线启动时,工人就开始工作,不停的接收生产需求,然后处理这些需求。如果工人生产速度较快,有可能出现全部需求处理完了,还没有新需求到来。如果工人生产速度较慢,有可能出现生产需求的挤压。无论是那种情况都需要采用生产--消费模式来确保提交生产需求的线程和处理生产需求的线程要相互同步。
4,代码实现
1) 定义生产需求类
package workerthread.study;
public class Request {
private String name;
private int number;
public Request(String name, int number)
{
this.name=name;
this.number=number;
}
public void handel()
{
System.out.println("Thread:"+Thread.currentThread().getName()+" handel request "+name+" and number" +number);
}
}
2)定义工人类
package workerthread.study;
public class Worker extends Thread {
Channel channel;
public Worker( Channel channel)
{
this.channel=channel;
}
public void run()
{
while (true)
{
//不停的从生产线获取需求,并处理该需求
channel.takeRequest().handel();
}
}
}
3)定义生产线类
package workerthread.study;
import java.util.ArrayList;
import java.util.List;
public class Channel {
private int MaxQequest=10; //生产线最大能接收的生产需求数量
private List<Request> requests=new ArrayList<>();
private Worker[] workers;
public Channel(int workerNumber)
{//定义生产线工人数量
workers=new Worker[workerNumber];
for(int i=0;i<workerNumber;i++)
{
workers[i]=new Worker(this);
}
}
public void startWork()
{
for(int i=0;i<workers.length;i++)
{
workers[i].start();
}
}
public synchronized void putRequest(Request request)
{
while(requests.size()>=this.MaxQequest)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
requests.add(request);
notifyAll();
}
public synchronized Request takeRequest()
{
while(requests.size()<=0)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Request request=requests.remove(0);
notifyAll();
return request;
}
}
4)启动3个不同Client和生产线,3个不同的Client定期往生产线发送5个生产需求
package workerthread.study;
public class Client {
public static void main(String[] args) {
Channel channel = new Channel(3);
channel.startWork();
Thread client1 = new Thread() {
public void run() {
int requestNumber=1;
for(int i=0;i<5;i++)
{
Request request=new Request("client1",requestNumber);
try {
Thread.sleep(100);
requestNumber++;
channel.putRequest(request);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread client2 = new Thread() {
public void run() {
int requestNumber=1;
for(int i=0;i<5;i++)
{
Request request=new Request("client2",requestNumber);
try {
Thread.sleep(100);
requestNumber++;
channel.putRequest(request);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread client3 = new Thread() {
public void run() {
int requestNumber=1;
for(int i=0;i<5;i++)
{
Request request=new Request("client3",requestNumber);
try {
Thread.sleep(100);
requestNumber++;
channel.putRequest(request);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
client1.start();
client2.start();
client3.start();
}
}
5)运行结果,可以看到不同的Client发送的生产需求分别由不同的Worker来处理,两者之间没有任何的一一对应关系
Thread:Thread-2 handel request client3 and number1
Thread:Thread-0 handel request client1 and number1
Thread:Thread-2 handel request client2 and number1
Thread:Thread-2 handel request client1 and number2
Thread:Thread-1 handel request client3 and number2
Thread:Thread-1 handel request client2 and number2
Thread:Thread-1 handel request client3 and number3
Thread:Thread-2 handel request client1 and number3
Thread:Thread-1 handel request client2 and number3
Thread:Thread-2 handel request client3 and number4
Thread:Thread-1 handel request client1 and number4
Thread:Thread-2 handel request client2 and number4
Thread:Thread-1 handel request client3 and number5
Thread:Thread-2 handel request client1 and number5
Thread:Thread-2 handel request client2 and number5