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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李文富 中级黑马   /  2012-5-31 13:54  /  5188 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

import java.util.Random;
public class ThreadScopeShareData {
/**
  * @param args
  */
        private static  int data = 0;
        public static void main(String[] args) {
             // TODO Auto-generated method stub
                      for(int i =0 ;i<2;i++){
                           new Thread(new Runnable(){
                                 @Override
                                  public void run() {
                                     data = new Random().nextInt();
                                     // TODO Auto-generated method stub
                                    System.out.println(Thread.currentThread().getName()+"put data"+data);
                                    new A().get();
                                    new B().get();
                                  }
   
                           }).start();
                     }
  }

static class A{
public void get() {
           // TODO Auto-generated method stub
           System.out.println("A "+Thread.currentThread().getName()+"   data   "+data);
}

}
static class B{
public void get() {
         // TODO Auto-generated method stub
          System.out.println("B "+Thread.currentThread().getName()+"data "+data);
       }
     }
}
运行如下:
Thread-0  put data-1216341610
Thread-1  put data-1216341610
A Thread-0   data -1216341610
A Thread-1   data -1216341610
B Thread-0   data -1216341610
B Thread-1   data -1216341610
请问为什么thread -0 ,thread-1中 new Random().nextInt()的值是一样的,并没有随机产生;

6 个回复

倒序浏览
可能是因为几个个线程启动的时间相差无几,而不同线程调用new Random().nextInt();
函数时相对是独立的,因而产生的随机数序列也就是相同的。
回复 使用道具 举报
因为你定义的Data是静态(static)的,静态的变量只共享一个副本,所以当它一初始化后,值会在整个类中共享。
我不知道你要的是不是这个意思,简单在你的代码上改动了一下:
import java.util.Random;
public class ThreadScopeShareData implements Runnable {
/**
  * @param args
  */
    public static void main(String[] args) {
         // TODO Auto-generated method stub
                      for(int i =0 ;i<2;i++){
                              ThreadScopeShareData r = new ThreadScopeShareData();
                           new Thread(r).start();
                           }
                      }


@Override

        public void run() {
                int data = 0;
                data = new Random().nextInt();
                System.out.println(Thread.currentThread().getName()+"put data"+data);
                System.out.println("A "+Thread.currentThread().getName()+"   data   "+data);
                System.out.println("B "+Thread.currentThread().getName()+"   data   "+data);
               
                }


}
回复 使用道具 举报
本帖最后由 刘伯阳 于 2012-5-31 14:47 编辑

因为你的data是静态(static)的,所以它会共享一个副本,当第一个随机数生成之后,被整个类共享,所以它的值不会改变。
我不知道你要实现什么功能,在你的代码的基础上改了一下:
import java.util.Random;
public class ThreadScopeShareData implements Runnable {

    public static void main(String[] args) {
                      for(int i =0 ;i<2;i++){
                              ThreadScopeShareData r = new ThreadScopeShareData();
                           new Thread(r).start();
                           }
                      }


@Override

        public void run() {
                int data = 0;
                data = new Random().nextInt();
                System.out.println(Thread.currentThread().getName()+"put data"+data);
                System.out.println("A "+Thread.currentThread().getName()+"   data   "+data);
                System.out.println("B "+Thread.currentThread().getName()+"   data   "+data);
               
                }


}

希望能帮助到您
回复 使用道具 举报
new Random().nextInt()需要填入参数:比如new Random().nextInt(10)参数0-9的随机数
回复 使用道具 举报
刘伯阳 发表于 2012-5-31 14:46
因为你的data是静态(static)的,所以它会共享一个副本,当第一个随机数生成之后,被整个类共享,所以它的 ...

这是个线程范围内共享数据的问题,实现不同的线程如:Thread 0 ,Thread 1 ;这两个线程拿的都是自己的数据;经过改良后的写法是:
import java.util.Random;


public class ThreadLocalTest {
        /**
         * @param args
         */
        private static ThreadLocal<Integer> x= new ThreadLocal<Integer>();
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                for(int i =0 ;i<2;i++){
                        new Thread(new Runnable(){
                        @Override
                                public void run() {
                                int data = new Random().nextInt();
                                x.set(data);
                                        // TODO Auto-generated method stub
                                        System.out.println(Thread.currentThread().getName()+"put data"+data);
                                        MyThreadData.getThreadInstance().setName("name"+data);
                                        MyThreadData.getThreadInstance().setAge(data);
                                        new A().get();
                                        new B().get();
                                }
                       
                        }).start();
                        }
                }


static class A{
        public void get() {
                // TODO Auto-generated method stub
                int data =x.get();
                System.out.println("A "+Thread.currentThread().getName()+"data "+data);
                MyThreadData myData = MyThreadData.getThreadInstance();
                System.out.println("A "+Thread.currentThread().getName()+"getmydata "+myData.getName()+
                " "+myData.getAge());
        }
}

static class B{
        public void get() {
                // TODO Auto-generated method stub
                int data =x.get();
                System.out.println("B"+Thread.currentThread().getName()+"data "+data);
                MyThreadData myData = MyThreadData.getThreadInstance();
                System.out.println("B "+Thread.currentThread().getName()+"getmydata "+myData.getName()+
                " "+myData.getAge());
        }
       
}
}

class MyThreadData{
        private MyThreadData(){}
        public static synchronized MyThreadData getThreadInstance(){
                MyThreadData instance = map.get();
                if (instance == null){
                        instance = new MyThreadData();
                        map.set(instance);
                }
               
                return instance;
        }
        //private static MyThreadData instance =null;
        private static ThreadLocal<MyThreadData> map = new ThreadLocal<MyThreadData>();
        private String name;
        private int age;
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
        public int getAge() {
                return age;
        }
        public void setAge(int age) {
                this.age = age
        }
}
现在的问题是像提问中遇到的,是线程切换太快而导致使用到random数据时一样的?
回复 使用道具 举报
黑马11期李项京 发表于 2012-5-31 14:59
new Random().nextInt()需要填入参数:比如new Random().nextInt(10)参数0-9的随机数

不写也是可以的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马