理解
流水线工厂模式是指利用线程实现让代码运行像工厂的流水线工作一样,让我们被输入的很多“产品“,在流水线上经历多个任务,而在多个线程同时工作时,减少了一步一步运行的时间损耗。
任务内容
这里我们用num作为我们的产品,定义三个方法,作为需要按顺序实行的任务
public class Task {
int num;
public void task1(){
num=20;
}
public void task2(){
num*=10;
}
public void task3(){
num*=num;
}
}
如果我们需要产出500个num,而这里正确的输出结果是40000
任务对象自动生产线程
所以我们现在来实现用线程实现500个任务
首先我们需要一个数列来存放500个对象,并实现讲500个对象放在其中
ArrayList<Task> taskList ;
public void run() {
for (int i = 0; i < 500; i++) {
Task task=new Task();
taskList.add(task);
}
System.out.println("自动生成任务工作线程已经完成"+taskList.size());
}
任务实现线程
接着我们来用实现每个任务实现的线程
public class Task_1_Thread implements Runnable{
ArrayList<Task> taskList;
public void setTaskList(ArrayList<Task> taskList) {
this.taskList = taskList;
}
@Override
public void run() {
while (true){
//降低速度
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int count=0;//计算进度
System.out.println("执行任务1");
for (int i = 0; i < taskList.size(); i++) {
Task task=taskList.get(i);
task.task1();
count++;
}
if (count==500){
System.out.println("任务1结束");
break;//结束循环
}
}
}
}
class Task_2_Thread implements Runnable{
ArrayList<Task> taskList;
public void setTaskList(ArrayList<Task> taskList) {
this.taskList = taskList;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int count=0;
System.out.println("执行任务2");
for (int i = 0; i < taskList.size(); i++) {
Task task=taskList.get(i);
task.task2();
count++;
}
if (count==500){
System.out.println("任务2结束");
break;
}
}
}
}
class Task_3_Thread implements Runnable{
ArrayList<Task> taskList;
public void setTaskList(ArrayList<Task> taskList) {
this.taskList = taskList;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int count=0;
System.out.println("执行任务3");
for (int i = 0; i < taskList.size(); i++) {
Task task=taskList.get(i);
task.task3();
count++;
}
if (count==500){
System.out.println("任务3结束");
break;
}
}
}
}
主程序实现
接着我们来用主程序实现我们的流水线生产
生成并启动各个线程
首先创建一个数列来存放对象,再启动AutoCreataTask生成对象在其中,然后启动实现三个任务的线程
public class Manage {
public static void main(String[] args) {
ArrayList<Task> taskList=new ArrayList<>();
//启动线程,生成500个对象"产品"
AutoCreatTask1 autoCreatTask1=new AutoCreatTask1(taskList);
Thread auto1=new Thread(autoCreatTask1);
auto1.start();
//创建流水线,启动实现三个任务的线程
Task_1_Thread task_1_thread=new Task_1_Thread(taskList);
Task_2_Thread task_2_thread=new Task_2_Thread(taskList);
Task_3_Thread task_3_thread=new Task_3_Thread(taskList);
Thread t1=new Thread(task_1_thread);
Thread t2=new Thread(task_2_thread);
Thread t3=new Thread(task_3_thread);
t1.start();
t2.start();
t3.start();
}
}
等待线程任务结束后,我们使用join方法,提交线程去执行,知道线程执行完成后再往后继续执行代码
//等待线程任务结束
auto1.join();
t1.join();
t2.join();
t3.join();
for (int i = 0; i < taskList.size(); i++) {
System.out.println(taskList.get(i).num);
}
结果
我们可以看到结果有问题
改正
这是因为我们没有设置一个属于对象能否进行下一步的标签,而线程运行时是不会分辨其对象能不能进行下一步的,所以我们要加上这个标签
boolean flag1;
boolean flag2;
boolean flag3;
public boolean task1(){
if(!flag1){
num=20;
flag1=true;
return true;
}
return false;
}
public boolean task2(){
if(!flag2&&flag1){
num*=10;
flag2=true;
return true;
}
return false;
}
public boolean task3(){
if (!flag3&&flag2&&flag1){
num*=num;
flag3=true;
return true;
}
return false;
}
然后在我们实现任务的线程出加上标签识别的代码
if (task.flag1){
count++;
}
...
if (task.flag2){
count++;
}
...
if (task.flag3){
count++;
}
结果
这样我的产品就正确产出来
总结
这个代码是按照几个板块分开写的,即任务内容,任务对象生成线程,任务实现线程组,主程序
新方法学习:join方法,用于提交线程去执行,知道线程执行完成在往后执行代码
对于流水线工厂模式代码,我们需要为产品贴上“标签”并辨别产品是否可以进行下一步