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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© NNERO 中级黑马   /  2014-4-25 21:39  /  943 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 NNERO 于 2014-4-26 09:53 编辑
  1. public class Text111
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Res r1 = new Res("nero",18);
  6.                 Thread t1 = new Thread(r1);
  7.                 Thread t2 = new Thread(r1);
  8.                 Thread t3 = new Thread(r1);
  9.                 Thread t4 = new Thread(r1);
  10.                
  11.                 t1.start();
  12.                 t2.start();
  13.                 t3.start();
  14.                 t4.start();
  15.         }
  16. }
  17. class Res implements Runnable{
  18.         String name;
  19.         int age;
  20.         int count = 100;
  21.         Object obj = new Object();
  22.         
  23.         public Res(String name, int age) {
  24.                 super();
  25.                 this.name = name;
  26.                 this.age = age;
  27.         }

  28.         public void run(){
  29.                 while(true){
  30.                         
  31.                         synchronized (obj) {
  32.                                 count--;
  33.                                 System.out.println(Thread.currentThread().getName()+"..."+name+"..."+age+"..."+count);
  34.                                 if(count<0)
  35.                                         break;
  36.                         }
  37.                         
  38.                 }
  39.         }
  40. }
复制代码
上面的这个程序,用4个线程来运行同一对象,如果没用同步代码块,我知道
这里就会出安全问题,导致数据错误。
但是我这里也用了同步代码块了。最后打印结果会有-1,-2,-3,-4出现,这是怎么回事?
应该线程安全了啊。求解。。。

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

4 个回复

倒序浏览
本帖最后由 展展 于 2014-4-25 21:48 编辑
  1.     public void run(){
  2.                 while(true){
  3.                           if(count<0)
  4.                                         break;

  5.                         synchronized (obj) {
  6.                                 count--;
  7.                                 System.out.println(Thread.currentThread().getName()+"..."+name+"..."+age+"..."+count);
  8.                               
  9.                         }
  10.                         
  11.                 }
  12.         }
复制代码


把if(count<0)
        break;

放到while下面可能会好一点,你想想有个线程运行到if这时count==0,但是有的线程刚刚运行到count--
这样就会出现负数了。
回复 使用道具 举报
第一,你写的代码实现了线程同步。
第二,因为你在同步代码块中是先让count--然后再打印出count最后再判断count是不是小于0,然后退出循环,所以就很容易理解为什么会打印出-1、-2、-3、-4了,如果你先判断count是不是小于0然后再输出count的话,自然就没有小于0的值出现了,只要你明白了先后顺序自然就明白了为什么会输出这样的结果了。。
回复 使用道具 举报
你break的是当前的线程,不是所有的线程。其他的线程可能停在同步前一个语句,等待你当前线程结束后进去,然后继续--输出,最后才是判断,你最好是把判断放到前面去,先判断在输出就不会了。
回复 使用道具 举报
理解了,,就是判断顺序的问题了。 谢谢各位
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马