黑马程序员技术交流社区

标题: 线程问题 [打印本页]

作者: NNERO    时间: 2014-4-25 21:39
标题: 线程问题
本帖最后由 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出现,这是怎么回事?
应该线程安全了啊。求解。。。

作者: 展展    时间: 2014-4-25 21:47
本帖最后由 展展 于 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--
这样就会出现负数了。
作者: 世界公民    时间: 2014-4-25 21:54
第一,你写的代码实现了线程同步。
第二,因为你在同步代码块中是先让count--然后再打印出count最后再判断count是不是小于0,然后退出循环,所以就很容易理解为什么会打印出-1、-2、-3、-4了,如果你先判断count是不是小于0然后再输出count的话,自然就没有小于0的值出现了,只要你明白了先后顺序自然就明白了为什么会输出这样的结果了。。
作者: 你为谁归来    时间: 2014-4-25 22:37
你break的是当前的线程,不是所有的线程。其他的线程可能停在同步前一个语句,等待你当前线程结束后进去,然后继续--输出,最后才是判断,你最好是把判断放到前面去,先判断在输出就不会了。
作者: NNERO    时间: 2014-4-26 09:52
理解了,,就是判断顺序的问题了。 谢谢各位




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