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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨长川 中级黑马   /  2013-4-10 16:45  /  1231 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨长川 于 2013-4-14 14:22 编辑
  1. package _7_26;

  2. import java.util.Random;

  3. public class ThreadScopeShareData2 {

  4.         private static int data = 0;
  5. //        private static Map<Thread, Integer> threadData = new HashMap<Thread, Integer>();
  6.         public static void main(String[] args) {
  7.                 for(int i=0;i<2;i++){
  8.                         new Thread(new Runnable(){
  9.                                 @Override
  10.                                 public void run() {
  11.                                          data = new Random().nextInt();
  12.                                         System.out.println(Thread.currentThread().getName()
  13.                                                         + " has put data :" + data);
  14. //                                        threadData.put(Thread.currentThread(), data);
  15.                                         new A().get();
  16.                                         new B().get();
  17.                                 }
  18.                         }).start();
  19.                 }
  20.                 new Thread(new Runnable(){
  21.                         @Override
  22.                         public void run() {
  23.                                  data = new Random().nextInt();
  24.                                 System.out.println(Thread.currentThread().getName()
  25.                                                 + " has put data :" + data);
  26. //                                threadData.put(Thread.currentThread(), data);
  27.                                 new A().get();
  28.                                 new B().get();
  29.                         }
  30.                 }).start();
  31.         }
  32.         
  33.         static class A{
  34.                 public void get(){
  35. //                        int data = threadData.get(Thread.currentThread());
  36.                         System.out.println("A from " + Thread.currentThread().getName()
  37.                                         + " get data :" + data);
  38.                 }
  39.         }
  40.         
  41.         static class B{
  42.                 public void get(){
  43. //                        int data = threadData.get(Thread.currentThread());                        
  44.                         System.out.println("B from " + Thread.currentThread().getName()
  45.                                         + " get data :" + data);
  46.                 }               
  47.         }
  48. }
复制代码
for循环里的两个线程为什么生成的随机数都一样??
在for循环外面新建一个线程,却能生成不同的随机数?谁给解释一下,这个很蹊跷。
---------------运行结果:------------------
Thread-0 has put data :1500315473
Thread-1 has put data :1500315473
Thread-2 has put data :445127673
A from Thread-0 get data :445127673
A from Thread-2 get data :445127673
A from Thread-1 get data :445127673
B from Thread-1 get data :445127673
B from Thread-2 get data :445127673
B from Thread-0 get data :445127673

就看前三行,前两个线程产生的随机数和后一个不同,为什么啊?按理说应该是三个都不同才对,前两个相同,还能是因为for循环里的两个线程顺便就把变量共享了么??

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

1 个回复

倒序浏览
本帖最后由 李罡 于 2013-4-10 18:03 编辑
  1. <p>package cn.itcast.day1;</p><p> </p><p>import java.util.Random;
  2. </p><p>public class ThreadScopeShareData2 {

  3.         private static int data = 0;
  4.         

  5. //        private static Map<Thread, Integer> threadData = new HashMap<Thread, Integer>();

  6.         public static void main(String[] args) {

  7.                 for(int i=0;i<2;i++){

  8.                         new Thread(new Runnable(){
  9.                         

  10.                                 @Override

  11.                                 public void run() {
  12.                                  synchronized(ThreadScopeShareData2.class){//加一个锁

  13.                                          data = new Random().nextInt();

  14.                                         System.out.println(Thread.currentThread().getName()
  15.                                                         + " has put data :" + data);

  16. //                                        threadData.put(Thread.currentThread(), data);

  17.                                         new A().get();

  18.                                         new B().get();
  19.                                  }

  20.                                 }

  21.                         }).start();

  22.                 }

  23.                 new Thread(new Runnable(){

  24.                         @Override

  25.                         public void run() {
  26.                          synchronized(ThreadScopeShareData2.class){//加一个锁

  27.                                  data = new Random().nextInt();

  28.                                 System.out.println(Thread.currentThread().getName()
  29.                                                 + " has put data :" + data);

  30. //                                threadData.put(Thread.currentThread(), data);

  31.                                 new A().get();

  32.                                 new B().get();
  33.                          }

  34.                         }

  35.                 }).start();

  36.         }

  37.         

  38.         static class A{

  39.                 public void get(){

  40. //                        int data = threadData.get(Thread.currentThread());

  41.                         System.out.println("A from " + Thread.currentThread().getName()
  42.                                         + " get data :" + data);

  43.                 }

  44.         }

  45.         

  46.         static class B{

  47.                 public void get(){

  48. //                        int data = threadData.get(Thread.currentThread());                        

  49.                         System.out.println("B from " + Thread.currentThread().getName()
  50.                                         + " get data :" + data);

  51.                 }               
  52.         }

  53. }
  54. </p>
复制代码
这是由于多线程共同运行造成的!你没有给他们同一个锁!三个线程一起运行,有可能线程1拿到执行权执行到data = new Random().nextInt();时,这时线程0拿到执行权,重新给data赋 一个值,打印出一个数据后执行权又被线程1抢走了,线程1接下来后面打印数据的操作,可刚打印出一个数据执行权被线程2抢走了,线程2重新给data赋值,而data是共享数据,所以接下来线程0,1,2打印出来的全是同一个数据了。
你多运行几次,有可能会出现三个不同的数据,每个数据都被打印3次。

代码如上所示,在第19行和44行给线程加同一个锁后,问题得以解决,每个线程产生不同的数据,每个数据打印3次。



评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 寝室网坏了,海霞帮忙呢,有疏漏,多担待了.

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马