javaee论坛

普通会员

225648

帖子

329

回复

343

积分

楼主
发表于 2019-10-30 14:58:32 | 查看: 115 | 回复: 3

Worker的意思是工作的人。在WorkerThread模式里,工人线程将逐个取回任务并进行处理。当所有工作全部完成后,工人线程会等待新的工作到来;

如果从“工人聚集”的来看,该模式也可以称为“线程池”模式;

WorkerThread使用场景提高吞吐量:避免启动线程所需要花费的时间;当然,代价是内存空间,因为有多个“工人”聚集嘛;调用与执行分离:调用意味着任务进入了“线程池”;而“工人”线程的处理才代表着任务的执行;WorkerThread示例代码分析//Worker线程池publicclassChannel{privatestaticfinalintMAX_REQUEST=100;privatefinalRequest[]requestQueue;privateinttail;privateinthead;privateintcount;privatefinalWorkerThread[]threadsPool;publicChannel(intthreads){this.requestQueue=newRequest[MAX_REQUEST];this.head=0;this.tail=0;this.count=0;threadsPool=newWorkerThread[threads];for(inti=0;i<threadsPool.length;i++){threadsPool[i]=newWorkerThread("Worker-"+i,this);}}publicvoidstartWorkers(){for(inti=0;i<threadsPool.length;i++){threadsPool[i].start();}}publicsynchronizedvoidputRequest(Requestrequest){while(count>=requestQueue.length){try{wait();}catch(InterruptedExceptione){e.printStackTrace();}}requestQueue[tail]=request;tail=(tail+1)%requestQueue.length;count++;notifyAll();}publicsynchronizedRequesttakeRequest(){while(count<=0){try{wait();}catch(InterruptedExceptione){e.printStackTrace();}}Requestrequest=requestQueue[head];head=(head+1)%requestQueue.length;count--;notifyAll();returnrequest;}}//客户线程,发送请求publicclassClientThreadextendsThread{privatefinalChannelchannel;privatestaticfinalRandomrandom=newRandom();publicClientThread(Stringname,Channelchannel){super(name);this.channel=channel;}publicvoidrun(){try{for(inti=0;true;i++){Requestrequest=newRequest(getName(),i);channel.putRequest(request);Thread.sleep(random.nextInt(1000));}}catch(InterruptedExceptione){e.printStackTrace();}}}//工人线程,处理请求publicclassWorkerThreadextendsThread{privatefinalChannelchannel;publicWorkerThread(Stringname,Channelchannel){super(name);this.channel=channel;}publicvoidrun(){while(true){Requestrequest=channel.takeRequest();request.execute();}}}//模拟请求publicclassRequest{privatefinalStringname;privatefinalintnumber;privatestaticfinalRandomrandom=newRandom();publicRequest(Stringname,intnumber){this.name=name;this.number=number;}publicvoidexecute(){System.out.println(Thread.currentThread().getName()+"executes"+this);try{Thread.sleep(random.nextInt(1000));}catch(InterruptedExceptione){e.printStackTrace();}}@OverridepublicStringtoString(){return"[Requestfrom"+name+"NO."+number+"]";}}//启动类publicclassTester{publicstaticvoidmain(String[]args){Channelchannel=newChannel(5);channel.startWorkers();newClientThread("Alice",channel).start();newClientThread("Bobby",channel).start();newClientThread("Chris",channel).start();}}WorkerThread模式的理解

WorkerThread模式实现了调用和执行分离;而ThreadPerMessage模式也实现了同样的效果;不同的是ThreadPerMessage对于每个请求会创建一个线程,而WorkerThread则事先创建了许多线程;相当于对线程进行了缓存和重用;

ClientThread相当于Producer,不断地生产Request;然后Channel相当于Table,而WorkerThread则相当于Consumer,不断地处理Request;不同的是Channel缓存了WorkerThread,相当于把Consumer和Table绑在了一起;从这个角度来看,WorkerThread和Producer-Consumer模式很类似;只是角色各有不同:WorkerThread模式中,只出现了两个角色:请求者和缓冲池;而Producer-Consumer模式则有三个角色:Producer-Buffer-Consumer;Buffer是独立的;

前面在ThreadPerMessage模式中,提到“从处理方来看,则没有顺序了,不仅任务结束时无序的,甚至连任务的开始也是无序的”;实际上,这个“无序”是在请求者的角度来看。从Channel角度来看,只是对顺序没有做处理而已,实际上只要想控制,那么Channel是可以控制“执行”顺序的;因为“调用和执行”是分离的嘛;Client负责调用;Worker负责执行;而作为Worker的管理者——Channel自然可以对“执行”做出控制!


普通会员

0

帖子

256

回复

258

积分
沙发
发表于 2021-04-20 19:26:32

围观

普通会员

0

帖子

307

回复

311

积分
板凳
发表于 2022-05-11 02:11:10

谢谢楼主分享

普通会员

1

帖子

283

回复

291

积分
地板
发表于 2023-08-03 16:29:24

百因必有果你的报应就是我

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017