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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lwy0319 高级黑马   /  2014-3-18 03:48  /  1339 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 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, 下载次数: 1)

新建位图图像.png

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

4 个回复

倒序浏览
线程没有同步每次进行的结果都不一样,你可以多运行几次。
回复 使用道具 举报
这个毕向东老师在多线程视频,说售票,那个例子里面有讲过。
这是因为控制台,也是一种资源。
线程在抢占票后,需要在控制台输出。也存在资源竞争。
如下图:
红色标注线程2的输出,绿色标注线程1的输出:

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

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
线程有创建、运行、等待、阻塞等状态;
如果你的方法没有同步的话,访问此方法的多个线程都可以对方法中的数据进行修改,就会出现打印结果错误的情况。并且每次运行,结果都是不一样的,这就是多线程抢夺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

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
原来如此,发帖的时候还没学到同步。。原来a出现的顺序是双核问题。。而出现两个线程的a=10则是非同步所带来的安全隐患了。。看来还是得看完相关知识再有问题再发帖了。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马