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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

Great_Man

初级黑马

  • 黑马币:16

  • 帖子:8

  • 精华:0

© Great_Man 初级黑马   /  2014-6-18 12:03  /  1335 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

废话少说,直接上代码先。

01 class ThreadDemo{
02     //    定义全局变量
03     private static int x = 100;
04     public static void main(String[] args){
05         //创建两个线程
06         Demo d0 = new Demo();
07         new Thread(d0,"线程0").start();
08         Demo d1 = new Demo();
09         new Thread(d1,"线程1").start();
10     }
11     //线程Demo
12     static class Demo implements Runnable{//extends Thread{
13         //实现Runnable中的run方法。
14         public void run(){
15             for(;x>0;x--)
16                 System.out.println(Thread.currentThread().getName()+"  "+x);
17         }   
18    }
19 }

程序运行结果为:

线程1  100

线程0  100

线程1  99

线程0  98

线程1  97

线程0  96

……

分析:

开辟两个子线程,当线程1进入打印输出100时,线程0也进入打印100,然后x--,下一步将打印99。
问题:
为什么后面不会一起打印99呢?

另外:
我知道,如果这样做:

for(;x>0;)System.out.println(Thread.currentThread().getName()+"  "+x--);

将会从100到1全部单次输出,不会重复输出。

可见这样子,两个字线程不会同时进行执行System.out.println()。

评分

参与人数 1技术分 +2 收起 理由
李小然 + 2 对于这样的认真的学习,给你个赞~.

查看全部评分

9 个回复

倒序浏览
首先你这个程序安全性有问题,两个线程同时访问同一个变量,是肯定会出现错误信息的,两个100就是体现.
至于为什么后面不会出现两次99 . 是因为 最开始两个线程开启后第一次执行for循环的时候,在两个线程都还没有执行最后x--操作的时候,都先执行了打印语句,所以就会出现两个100, 这以后每个线程都必定会顺序执行-1操作,所以不会再出现重复, 有点不好讲这意思
  当你把x-- 放到输出语句的时候 也是会出现相同100的情况 你可以多试验几次 我已经试验过了.
  你放下来 其实也一样  打印语句执行完后, 再执行-1操作,  所以
System.out.println(Thread.currentThread().getName()+"  "+x--); 这句其实是两个步骤.

评分

参与人数 1技术分 +1 收起 理由
李小然 + 1 赞一个!

查看全部评分

回复 使用道具 举报
倪大大 发表于 2014-6-18 14:29
首先你这个程序安全性有问题,两个线程同时访问同一个变量,是肯定会出现错误信息的,两个100就是体现.
至于 ...

非常感谢你的回答。下面是我对程序的改进。
Object p = new Object();
                public void run(){
                        synchronized(p){
                        for(;x>0;x--)
                                System.out.println(Thread.currentThread().getName()+"  "+x);
                        }
                }
结果没有变化,同样输出了两个100.唯一的变化是,输出不是顺序递减的,比如97 98 96 94 95……
我进行了设置同步代码块,还是两个100,为何呢?
回复 使用道具 举报
Great_Man 发表于 2014-6-18 14:58
非常感谢你的回答。下面是我对程序的改进。
Object p = new Object();
                public void run(){

因为你的P 是局部变量,你new了两个Demo 其实是两个P  锁都不一样 怎么能同步?
你这个P要定义成全局变量 让两个类共享
回复 使用道具 举报
这是个概率问题,第一次的概率比较大,后面打印相同的概率比较小,但还是有可能的,你可以试试更大的数
回复 使用道具 举报
你可以回忆一下毕老师说的那两个条件:
1.两个线程
2.同一把锁

你改进后的代码不符合第二个条件。
回复 使用道具 举报
倪大大 发表于 2014-6-18 19:51
因为你的P 是局部变量,你new了两个Demo 其实是两个P  锁都不一样 怎么能同步?
你这个P要定义成全局变量  ...

你说得对,我已经搞定了
回复 使用道具 举报
rover0321 发表于 2014-6-18 20:00
你可以回忆一下毕老师说的那两个条件:
1.两个线程
2.同一把锁

这是因为我创建了两个Runnable实例。
回复 使用道具 举报
Great_Man 发表于 2014-6-20 23:46
这是因为我创建了两个Runnable实例。

在你的代码中两个实例 就是用了两把不同的锁。
回复 使用道具 举报
留个脚印 以后看
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马