黑马程序员技术交流社区

标题: 多线程共享属性问题 [打印本页]

作者: lwy0319    时间: 2014-3-18 03:48
标题: 多线程共享属性问题
本帖最后由 lwy0319 于 2014-3-22 00:15 编辑
  1. class MyThread implements Runnable{
  2.         private int a=10;
  3.         public void run() {
  4.                 for(int i=0;i<100;i++){
  5.                         if(this.a>0)
  6.                         System.out.print(Thread.currentThread().getName()+" a="+a--+" ");
  7.                 }
  8.         }
  9. }
  10. public class Demo {
  11.         public static void main(String[] args){
  12.                 MyThread mt = new MyThread() ;
  13.                 new Thread(mt,"线程1").start();
  14.                 new Thread(mt,"线程2").start();
  15.         }
  16. }
复制代码
多线程学得不太顺利。。我按照一个例子讲的为了区分Runnable接口子类和Thread类的区别(区别在于是否共享类属性),代码如上,但是运行发现还是跟理论上有点儿不同结果如图所示,感觉与理论结果差得并不离谱。请问是否是双核的原因?如果是双核原因,出来两个a=10可以理解,整体确实是递减显示的,可是为什么a=6会在倒数第二个显示?有一种a=6先运行后打印出来的感觉,但是我是在打印命令中才让a--的,感觉不应该出现顺序错乱。。


新建位图图像.png (148.44 KB, 下载次数: 10)

新建位图图像.png

作者: 无道    时间: 2014-3-18 07:59
线程没有同步每次进行的结果都不一样,你可以多运行几次。
作者: 水蓝    时间: 2014-3-18 09:51
这个毕向东老师在多线程视频,说售票,那个例子里面有讲过。
这是因为控制台,也是一种资源。
线程在抢占票后,需要在控制台输出。也存在资源竞争。
如下图:
红色标注线程2的输出,绿色标注线程1的输出:

你只要保证,线程2和线程1自身是递减的就可以了。

作者: 蒋珍珍    时间: 2014-3-18 10:42
线程有创建、运行、等待、阻塞等状态;
如果你的方法没有同步的话,访问此方法的多个线程都可以对方法中的数据进行修改,就会出现打印结果错误的情况。并且每次运行,结果都是不一样的,这就是多线程抢夺CPU执行权造成的(JVM在执行多线程程序时,用抢占方式或是分时间片方式来轮换执行各个线程)。
如你结果中a=6显示在最后,原因是当a=7时,线程二开始执行这句
System.out.print(Thread.currentThread().getName()+" a="+a--+" ")
代码,然后a的值变为了6,陷入了阻塞状态,CPU执行权被线程二抢走了,线程一就进入到方法体执行,执行到a--后,a的值变为5,在还没来得及打印a=6时,CPU执行权又被线程二抢走了,所以开始打印线程二 a=5....a=2,突然,线程一又重新获得CPU执行权,从阻塞状态变为运行状态,继续之前的打印操作:线程一 a=6
作者: lwy0319    时间: 2014-3-18 17:49
原来如此,发帖的时候还没学到同步。。原来a出现的顺序是双核问题。。而出现两个线程的a=10则是非同步所带来的安全隐患了。。看来还是得看完相关知识再有问题再发帖了。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2