计算任务,一个包含了2万个整数的数组,分拆了多个线程来进行并行计算,最后汇总出计算的结果。 用下面博主写的没有方法的代码运行就会发现问题。运行多次后,会发现最终得到的结果不一样,并且不正确。这就是多线程互相争抢资源的结果,那么我们怎么来把这个问题简单的解决一下了。下面就是博主对这个问题的解答过程。 我们通过三种方法(睡眠、合并、判断)来解决线程间抢资源的问题,会发现, 此方法也是和上面的方法也是一样,只是不用实现接口了,直接在主函数里面new 对象,那么在这简单描述一下。 博主为代码新人,欢迎大佬批评指正,也欢迎小白参考。谢谢!!!
用多线程对2万个整数的数组计算和,并得到结果。
具体题目
常见问题
多线程的创建方式:两种方法
方法一:Runnable接口
public class test { public static void main(String[] args) throws InterruptedException { /** * 计算任务,一个包含了2万个整数的数组,分拆了多个线程来进行并行计算,最后汇总出计算的结果。 */ int[] cs = new int[20000]; for (int i = 0; i < cs.length; i++) { cs[i] = i+1;//为什么加1:因为i是下标,起始值为0,我们输入的值从1开始,所有加1 } //创建实现类对象 Tesk tesk1 = new Tesk(1,5000,cs); Tesk tesk2 = new Tesk(5001,10000,cs); Tesk tesk3 = new Tesk(10001,15000,cs); Tesk tesk4 = new Tesk(15001,20000,cs); //创建子线程对象 Thread t1 = new Thread(tesk1); Thread t2 = new Thread(tesk2); Thread t3 = new Thread(tesk3); Thread t4 = new Thread(tesk4); //线程启动:开始运行 t1.start(); t2.start(); t3.start(); t4.start(); //方式一:睡眠:给子线程足够的时间计算,但是浪费时间。 Thread.sleep(1000); //延迟1000毫秒 System.out.println(tesk1.getsum()+tesk2.getsum()+tesk3.getsum()+tesk4.getsum()); } } class Tesk implements Runnable{ private int startnum;//开始数 private int endnum;//结尾数 private int sum;//和 private int[] is;//数组 // private boolean flag = true; public Tesk(int startnum, int endnum, int[] is) { this.startnum = startnum; this.endnum = endnum; this.is = is; } //重写Runnable中的run方法 @Override public void run() { for (int i = startnum; i <= endnum; i++) { this.sum +=is[i-1]; }//flag = false; } //因为是私有属性,所有通过一个方法来返回sum(计算和的结果) public int getsum() {//返回出各线程的计算和值 return this.sum; } }
public class test { public static void main(String[] args) throws InterruptedException { int[] cs = new int[20000]; for (int i = 0; i < cs.length; i++) { cs[i] = i+1;//为什么加1:因为i是下标,起始值为0,我们输入的值从1开始,所有加1 } //创建实现类对象 Tesk tesk1 = new Tesk(1,5000,cs); Tesk tesk2 = new Tesk(5001,10000,cs); Tesk tesk3 = new Tesk(10001,15000,cs); Tesk tesk4 = new Tesk(15001,20000,cs); //创建子线程对象 Thread t1 = new Thread(tesk1); Thread t2 = new Thread(tesk2); Thread t3 = new Thread(tesk3); Thread t4 = new Thread(tesk4); //线程启动:开始运行 t1.start(); t2.start(); t3.start(); t4.start(); //方法二: while (tesk1.isflag() || tesk2.isflag() || tesk3.isflag() || tesk4.isflag()) {//当每一个线程都运行完时,就会返回 } System.out.println(tesk1.getsum()+tesk2.getsum()+tesk3.getsum()+tesk4.getsum()); } } class Tesk implements Runnable{ private int startnum;//开始数 private int endnum;//结尾数 private int sum;//和 private int[] is;//数组 private boolean flag = true;//判断,现在状态为true public Tesk(int startnum, int endnum, int[] is) { this.startnum = startnum; this.endnum = endnum; this.is = is; } //重写Runnable中的run方法 @Override public void run() { for (int i = startnum; i <= endnum; i++) { this.sum +=is[i-1]; }flag = false; //运行完后就给flag赋值false; } //因为是私有属性,所有通过一个方法来返回sum(计算和的结果) public int getsum() {//返回出各线程的计算和值 return this.sum; } public boolean isflag() {//返回flag的状态 return flag; } }
public class test { public static void main(String[] args) throws InterruptedException { int[] cs = new int[20000]; for (int i = 0; i < cs.length; i++) { cs[i] = i+1;//为什么加1:因为i是下标,起始值为0,我们输入的值从1开始,所有加1 } //创建实现类对象 Tesk tesk1 = new Tesk(1,5000,cs); Tesk tesk2 = new Tesk(5001,10000,cs); Tesk tesk3 = new Tesk(10001,15000,cs); Tesk tesk4 = new Tesk(15001,20000,cs); //创建子线程对象 Thread t1 = new Thread(tesk1); Thread t2 = new Thread(tesk2); Thread t3 = new Thread(tesk3); Thread t4 = new Thread(tesk4); //线程启动:开始运行 t1.start(); t2.start(); t3.start(); t4.start(); //方法三:合并join方法为合并 t1.join(); t2.join(); t3.join(); t4.join(); System.out.println(tesk1.getsum()+tesk2.getsum()+tesk3.getsum()+tesk4.getsum()); } } class Tesk implements Runnable{ private int startnum;//开始数 private int endnum;//结尾数 private int sum;//和 private int[] is;//数组 public Tesk(int startnum, int endnum, int[] is) { this.startnum = startnum; this.endnum = endnum; this.is = is; } //重写Runnable中的run方法 @Override public void run() { for (int i = startnum; i <= endnum; i++) { this.sum +=is[i-1]; }flag = false; //运行完后就给flag赋值false; } //因为是私有属性,所有通过一个方法来返回sum(计算和的结果) public int getsum() {//返回出各线程的计算和值 return this.sum; } }
方法二:Thread类
public class Work { public static void main(String[] args) throws InterruptedException { //声明包含2万个整数的数组 int[] is = new int[20000]; //初始化数据 for (int i = 0; i < is.length; i++) { is[i] = (i+1); } MyThread t1 = new MyThread(0, 4999, is); MyThread t2 = new MyThread(5000, 9999, is); MyThread t3 = new MyThread(10000, 14999, is); MyThread t4 = new MyThread(15000, 19999, is); t1.start(); t2.start(); t3.start(); t4.start(); //数据错误的原因:4个子线程还没有执行完毕,主线程就抢到资源并输出结果 //解决方案:4个子线程全部执行完毕,再让主线程抢到资源 //1.休眠 // Thread.sleep(10); //2.获取线程状态 // while(t1.isFlag() || t2.isFlag() || t3.isFlag() || t4.isFlag()){ // } //3.合并 t1.join(); t2.join(); t3.join(); t4.join(); System.out.println(t1.getSum() + t2.getSum() + t3.getSum() + t4.getSum()); } } class MyThread extends Thread{ private int startIndex; private int endIndex; private int[] is; private int sum; private boolean flag = true; public MyThread(int startIndex, int endIndex, int[] is) { this.startIndex = startIndex; this.endIndex = endIndex; this.is = is; } @Override public void run() { for (int i = startIndex; i <= endIndex; i++) { sum += is[i]; } flag = false; } public int getSum() { return sum; } public boolean isFlag() { return flag; } }
总结
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算