A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

一个练习题,自己的算法感觉有点复杂,能不能用一个run方法实现?
  1. import java.util.Random;

  2. /*练习:声明一个共享数组,起两个线程,两个线程分别隔一段时间(可以写一个随机数),
  3. * 给数组中添加数据,每一个线程为数组添加3个数据即可。
  4. */
  5. public class Test11 {
  6.         public static void main(String[] args) {
  7.                 int [] arr = new int [6];
  8.                 ShareArray shareArray = new ShareArray(arr);
  9.                 Thread thread1 = new Thread(new AddValue1(shareArray));
  10.                 Thread thread2 = new Thread(new AddValue2(shareArray));
  11.                 thread1.start();
  12.                 thread2.start();

  13.         }
  14. }
  15. //定义多线程操作的资源
  16. class ShareArray {
  17.         int[] arr;
  18.         int i = 0;
  19.         boolean flag = false;

  20.         ShareArray(int[] arr) {
  21.                 this.arr = arr;
  22.         }
  23.         //给数组添加数据
  24.         public void setValue(int x) {
  25.                 arr[i] = x;
  26.                 System.out.println(Thread.currentThread().getName() + "添加了--->"
  27.                                 + arr[i]);
  28.                 i++;
  29.         }
  30. }
  31. //线程对资源的操作
  32. class AddValue1 implements Runnable {
  33.         ShareArray shareArray;
  34.         AddValue1(ShareArray shareArray){
  35.                 this.shareArray = shareArray;
  36.         }

  37.         @Override
  38.         public void run() {
  39.                 // TODO Auto-generated method stub
  40.                 for (int i = 0; i < 3; i++) {//让线程给数组循环添加数据
  41.                         synchronized (shareArray) {//给操作共享数据的语句加上同步,用资源类对象作为锁
  42.                                 if (shareArray.flag){
  43.                                         try {
  44.                                                 shareArray.wait();
  45.                                         } catch (InterruptedException e1) {
  46.                                                 // TODO Auto-generated catch block
  47.                                                 e1.printStackTrace();
  48.                                         }
  49.                                 }
  50.                                 try {
  51.                                         Thread.sleep(1000);
  52.                                 } catch (InterruptedException e) {
  53.                                         // TODO Auto-generated catch block
  54.                                         e.printStackTrace();
  55.                                 }
  56.                                 shareArray.setValue(new Random().nextInt(10));
  57.                                 shareArray.flag = true;
  58.                                 shareArray.notify();
  59.                         }
  60.                 }
  61.         }

  62. }

  63. class AddValue2 implements Runnable {
  64.         ShareArray shareArray;
  65.         AddValue2(ShareArray shareArray){
  66.                 this.shareArray = shareArray;
  67.         }

  68.         @Override
  69.         public void run() {
  70.                 // TODO Auto-generated method stub
  71.                 for (int i = 0; i < 3; i++) {
  72.                         synchronized (shareArray) {
  73.                                 if (!shareArray.flag){
  74.                                         try {
  75.                                                 shareArray.wait();
  76.                                         } catch (InterruptedException e1) {
  77.                                                 // TODO Auto-generated catch block
  78.                                                 e1.printStackTrace();
  79.                                         }
  80.                                 }
  81.                                 try {
  82.                                         Thread.sleep(1000);
  83.                                 } catch (InterruptedException e) {
  84.                                         // TODO Auto-generated catch block
  85.                                         e.printStackTrace();
  86.                                 }
  87.                                 shareArray.setValue(new Random().nextInt(10));
  88.                                 shareArray.flag = false;
  89.                                 shareArray.notify();
  90.                         }
  91.                 }
  92.         }

  93. }
复制代码


4 个回复

倒序浏览
他只是说每隔一段时间存入就行了,没必要交替吧。然后共享的数组和角标可以直接放在主类中。
  1. public class Gongxiang
  2. {
  3.         public int index=0;//在主类中设置索引并初始化以便其他类引用
  4.         public static void main(String[] args)
  5.         {
  6.                 int[] share=new int[6];//设置想要存入入局的数组
  7.                 Gongxiang gg=new Gongxiang();//创建一个主函数对象以得到共享的索引
  8.                
  9.                 //创建线程并启动
  10.                 Thread t1=new Thread(new WriteArr(share,gg),"1号线程");
  11.                 Thread t2=new Thread(new WriteArr(share,gg),"2号线程");
  12.                 t1.start();
  13.                 t2.start();               
  14.                
  15.                 //线程执行完后才能让主函数遍历数组
  16.                 try
  17.                 {
  18.                         t1.join();
  19.                         t2.join();
  20.                 }
  21.                 catch(Exception e)
  22.                 {
  23.                         e.printStackTrace();
  24.                 }
  25.                
  26.                 //遍历存入数据的数组
  27.                 for(int i:share)
  28.                         System.out.println(i);
  29.         }
  30. }

  31. class WriteArr implements Runnable
  32. {
  33.         private int[] share;
  34.         private Gongxiang gg;
  35.        
  36.         public WriteArr(int[] share,Gongxiang gg)//初始化构造函数,获取数组与主类对象
  37.         {
  38.                 this.share=share;
  39.                 this.gg=gg;
  40.         }
  41.        
  42.         public void run()
  43.         {
  44.                         for(int i=0;i<3;i++)//每个线程存3个数据
  45.                         {
  46.                                 try
  47.                                 {
  48.                                         Thread.sleep((int)(Math.random()*10));//每次睡眠一段时间再存
  49.                                 }
  50.                                 catch(Exception e)
  51.                                 {
  52.                                          e.printStackTrace();
  53.                                 }
  54.                                 synchronized(share)//同步加锁防止索引错误
  55.                                 {
  56.                                         this.share[gg.index++] = (int)(Math.random()*10);//存入随机数
  57.                                         System.out.println(Thread.currentThread().getName()+"存入了"+share[gg.index-1]);//输出存入信息
  58.                                 }
  59.                         }
  60.         }
  61. }
复制代码
回复 使用道具 举报
这样理解就简单多了
回复 使用道具 举报
冥夜 发表于 2014-12-8 19:40
他只是说每隔一段时间存入就行了,没必要交替吧。然后共享的数组和角标可以直接放在主类中。
...

这样能确保每个线程存三个数而不覆盖吗?
回复 使用道具 举报
DamonZh 发表于 2014-12-8 20:43
这样能确保每个线程存三个数而不覆盖吗?

是的,因为数组的索引是放置于主类中,而且主类对象有且只有一个,并且在更改索引的代码上加了锁,所以不会出现覆盖的问题。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马