动态域名网站,海外网络搭建,广东科技网站建设,网页设计制作网站下面先给出基础代码#xff0c;我会讲解一下各部分代码的作用以及他们之间的联系#xff0c;然后提出下面的代码的问题并提出几个解决方案 1.Task任务类 public class Task {int num;// num20 num *10;num*num;//4000 //任务Apublic void taskA(){num20;}//任务Bpublic void …下面先给出基础代码我会讲解一下各部分代码的作用以及他们之间的联系然后提出下面的代码的问题并提出几个解决方案1.Task任务类publicclassTask{intnum;// num20 num *10;num*num;//4000//任务ApublicvoidtaskA(){num20;}//任务BpublicvoidtaskB(){num*10;}//任务CpublicvoidtaskC(){num*num;}}2.主类importjava.util.ArrayList;publicclassMain{publicstaticvoidmain(String[]args){//定量任务ArrayListTasktasksnewArrayList();for(inti0;i500;i){tasks.add(newTask());}ThreadAtanewThreadA(tasks);ThreadBtbnewThreadB(tasks);ThreadCtcnewThreadC(tasks);ta.start();tb.start();tc.start();try{ta.join();tb.join();tc.join();}catch(InterruptedExceptione){thrownewRuntimeException(e);}for(inti0;itasks.size();i){System.out.print(tasks.get(i).num);}}}3.线程类importjava.util.ArrayList;publicclassThreadAextendsThread{ArrayListTasktasks;publicThreadA(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskA();}}}classThreadBextendsThread{ArrayListTasktasks;publicThreadB(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskB();}}}classThreadCextendsThread{ArrayListTasktasks;publicThreadC(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskC();}}}1.Task类作用他就是一个任务类里面有三个任务TaskA():将num增加20。TaskB():将num乘以10。TaskC():将num乘以自身。这个类会做为main类中动态数组Task的元素数组Task中的每一个元素都是一个Task类单元。实现这个功能的代码如下ArrayListTasktasksnewArrayList();for(inti0;i500;i){tasks.add(newTask());}那这个Task类和线程类有何联系首先main类中创建好动态数组并且把所有task类存入数组后每个线程类也同时会创建一个动态数组当main类中创建线程类的对象时即调用线程类的构造方法会把main中的动态数组传入线程类这时线程类中创建的动态数组就来接收main中传入的动态数组。ArrayListTasktasks;publicThreadA(ArrayListTasktasks){this.taskstasks;}2.线程类线程类的任务很简单明确线程A,B,C都会遍历动态数组储存的每个Task对象然后分别调用任务A,B,Cmain类main类的作用就是启动三个线程并且输出所有task对象的num最终值。问题这里存在并发编程问题三个线程并发地对同一个Task对象集合中地num值修改会使得有些方法调用失效。改进方法一自旋publicclassTask{intnum;booleanfA;booleanfB;booleanfC;// num20 num *10;num*num;//4000//任务ApublicvoidtaskA(){if(!fA){num20;fAtrue;}}//任务BpublicvoidtaskB(){if(!fBfA){num*10;fBtrue;}}//任务CpublicvoidtaskC(){if(!fCfB){num*num;fCtrue;}}}importjava.util.ArrayList;publicclassThreadAextendsThread{ArrayListTasktasks;publicThreadA(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){while(true){System.out.println(TA Run.....);intcount0;for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskA();if(task.fA){count;}}if(counttasks.size()){break;}}}}classThreadBextendsThread{ArrayListTasktasks;publicThreadB(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskB();}}}classThreadCextendsThread{ArrayListTasktasks;publicThreadC(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskC();}}}Task 类增加了三个布尔变量用于标记每个任务是否已完成 A、B、C 操作。taskA() 只有在 fA 为 false 时才执行执行后置 fA true。taskB() 要求 fB 为 false 且 fA 为 true 才执行即 A 已完成执行后置 fB true。taskC() 要求 fC 为 false 且 fB 为 true 才执行即 B 已完成执行后置 fC true。ThreadA 采用 while(true) 循环不断遍历所有任务并调用 taskA()直到所有任务的 fA 都为 true 才退出。这保证了所有任务的 A 操作最终都会执行。ThreadB 和 ThreadC 只是简单遍历一次所有任务调用对应的 taskB() 和 taskC()没有循环。解決方案二阻塞式publicclassTask{intnum;booleanfA;booleanfB;booleanfC;// num20 num *10;num*num;//4000//任务ApublicvoidtaskA(){if(!fA){num20;fAtrue;}}//任务BpublicvoidtaskB(){while(!fA){//阻塞操作}if(!fB){num*10;fBtrue;}}//任务CpublicvoidtaskC(){while(!fB){//阻塞操作}if(!fC){num*num;fCtrue;}}}importjava.util.ArrayList;publicclassThreadAextendsThread{ArrayListTasktasks;publicThreadA(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){// while (true) {// System.out.println(TA Run.....);// int count 0;for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskA();// if(task.fA){// count;// }}// if(counttasks.size()) {// break;// }}}classThreadBextendsThread{ArrayListTasktasks;publicThreadB(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){// while (true) {// System.out.println(TB Run.....);// int count 0;for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskB();// if(task.fB){// count;// }}// if(counttasks.size()) {// break;// }}}classThreadCextendsThread{ArrayListTasktasks;publicThreadC(ArrayListTasktasks){this.taskstasks;}publicvoidrun(){// while (true) {// System.out.println(TB Run.....);// int count 0;for(inti0;itasks.size();i){Tasktasktasks.get(i);task.taskC();// if(task.fC){// count;// }}// if(counttasks.size()) {// break;// }}}在 Task 类中taskB() 和 taskC() 分别加入了 while(!fA) {} 和 while(!fB) {} 循环。这意味着当线程 B 调用 taskB() 时会一直空转直到某个任务的 fA 变为 true表示该任务的 A 操作已完成才继续执行 num * 10。当线程 C 调用 taskC() 时会一直空转直到某个任务的 fB 变为 true表示该任务的 B 操作已完成才继续执行 num * num。线程 A、B、C 各自只遍历一次 tasks 列表依次对每个任务调用对应的方法。线程 A 不包含任何等待逻辑。