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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 当我遇上你 中级黑马   /  2015-1-16 11:56  /  2183 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. package Test;
  2. /*声明一个共享数组,起两个线程,两个线程分别隔一段时间(可以写一个随机数),
  3. 给数组中添加数据,每一个线程为数组添加3个数据即可。*/

  4. /*1、首先共添加6个数据,每个线程添加3个,数组需要同步
  5.   2、随机数每个线程都用,故写在run方法中
  6. */


  7. import java.util.Random;

  8. //声明一个共享数组,起两个线程,
  9. //两个线程分别隔一段时间(可以写一个随机数),给数组中添加数据,
  10. //每一个线程为数组添加3个数据即可。
  11. public class Test16 {
  12.         //写一个类实现Runnable接口,创建两个Thread对象传入该类
  13.            //多线程操作共享数组需要同步synchronize
  14.        public static void main(String...args){
  15.                fillArray fa = new fillArray();
  16.                Thread t1 = new Thread(fa);
  17.                Thread t2 = new Thread(fa);
  18.                t1.start();
  19.                t2.start();
  20.               
  21.        }
  22. }
  23. class fillArray implements Runnable{
  24.     //定义共享数组
  25.         int[] arr = new int[6];
  26.         //产生随机数
  27.         Random r = new Random();
  28.         Object lock=new Object();
  29.     int count = 0;
  30.         public void run() {
  31.                 // 同步代码块
  32.                
  33.                 while(true)
  34.                 {
  35.                         synchronized(lock)
  36.                         {

  37.                                 if (count<arr.length) {
  38.                                         int num = r.nextInt(20);
  39.                                         System.out.println(Thread.currentThread().getName()+"向数组中加入了"+num);
  40.                                         arr[count] = num;
  41.                                         count++;
  42.                                         try {
  43.                                                 this.wait();
  44.                                         } catch (Exception e) {
  45.                                                 e.printStackTrace();
  46.                                         }
  47.                                 }
  48.                         }
  49.                 }

  50. //                System.out.println(Arrays.toString(arr));测试结果
  51.         }
  52.        
  53. }
复制代码

如果按照sleep()来实现 的话应该不能够严格的交替运行,另外的线程不一定抢得到CPU执行权,用wait(),notify()的话应该可以实现,代码怎么写呢?    还有这个代码是如何实现的呢?

6 个回复

正序浏览
看别人代码是一件很头疼的事!
回复 使用道具 举报

public class Demo13 {
        public static void main(String[] args) {
                fillArray fa = new fillArray();
        Thread t1 = new Thread(fa);
        Thread t2 = new Thread(fa);
        t1.start();
        t2.start();
        
}
}
class fillArray implements Runnable{
//定义共享数组
int[] arr = new int[6];
//产生随机数
Random r = new Random();
Object lock=new Object();
int count = 0;
public void run() {
         // 同步代码块
         
         while(true)   //这里循环如何停止??? 注意要设置一个可以让他停止的条件.
         {
                 synchronized(lock)  //自己定义的object对象锁.
                 {

                         if (count<arr.length) {  //这里是一个判断,但是外循环无限循环???
                                 int num = r.nextInt(20);
                                 System.out.println(Thread.currentThread().getName()+"向数组中加入了"+num);
                                 arr[count] = num;
                                 count++;
                                 try {
                          //                       lock.notifyAll();  //我在这里唤醒所有,结果唤醒别人,我自己在下面执行后睡着了...
                                         lock.wait(10); //this是谁?应该是线程对象.那么线程对象在这里都睡着谁唤醒?
                                         /**
                                          * 这里设置notifyAll没有意义.因为只有一个锁.
                                          * 具体多个锁,我没有实现.你自己可以去尝试创建多个锁对象,然后互相唤醒....
                                          * */
                                 } catch (Exception e) {
                                         e.printStackTrace();
                                 }
                                
                         }
                         else //让外循环停止条件.
                         {                             
                                 break;
                         }
                    //     System.out.println("1");
                 }
         }

//         System.out.println(Arrays.toString(arr));测试结果
        }
}
回复 使用道具 举报
碎流 发表于 2015-1-16 13:21
我自我觉得:
wait,notify这个应该是用在拥有不同锁对象的情况下,而这个只是存在一个锁,是没有必要的,也不 ...

额,本来想通过计数器奇偶数来控制两个线程相互唤醒的,可惜失败了,还有这个题目你认为该如何实现呢?
(有个地方我i没想明白,wait时当前线程会释放同步锁并等待,这时候其他线程就可能得到这个同步锁然后执行自己的线程程序,这时可以增加notify达到唤醒第一个wait的目的。绕住了,求解)
回复 使用道具 举报
本帖最后由 碎流 于 2015-1-16 13:23 编辑
当我遇上你 发表于 2015-1-16 12:43
好吧,时间改短了指定不对,还是wait配合notify来用靠谱,我正在想怎么实现一个对象两个线程相互唤醒怎么 ...

我自我觉得:
wait,notify这个应该是用在拥有不同锁对象的情况下,而这个只是存在一个锁,是没有必要的,也不可以实现的.
比如有两个锁,那么x锁在执行完毕之后唤醒y锁,这样可以.但是一个锁的情况下,a线程拿上锁之后,其他线程本来就
不可能执行的.只有a放弃锁,其他线程才会执行.那么a拿着锁唤醒,唤醒谁呢???

因此总结: wait,notify,notifyAll是用在多个锁之间,可能会产生死锁的情况下的.一个锁没有这个概念.一会我尝试一下多个锁的操作.可以试试看.
以上为我个人总结的,具体实现,这个还真没用多次尝试过,你如果尝试过了,告诉我结果...
回复 使用道具 举报
碎流 发表于 2015-1-16 12:12
总结一下吧,我自己也是可以学习下
1.使用sleep不可以实现交替运行,只会存在一个等待时间特点.
2.锁对象.wai ...

好吧,时间改短了指定不对,还是wait配合notify来用靠谱,我正在想怎么实现一个对象两个线程相互唤醒怎么实现
回复 使用道具 举报
总结一下吧,我自己也是可以学习下
1.使用sleep不可以实现交替运行,只会存在一个等待时间特点.
2.锁对象.wait(可以加入时间).
3.如何实现?首先是确定共享资源是什么?既然是共享资源是不是就应该存在一份?所以在创建的时候只有一个 fillArray对象.
4.多线程,有几个线程就Thread几次....让线程同时指向一个对象,那么这个对象中的数组,int变量等等都是共享的了.

总结:对象是实体的.线程是虚拟的.
实体的对象通过new操作来创建出来,虚拟的线程通过thread来创建出来.
所谓实现runnable,就是让类和thread协议声明共同可以执行线程数据的区域----run方法.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马