论坛首页 入门技术论坛

java多线程同步例子--求解答

浏览 3003 次
该帖已经被评为新手帖
作者 正文
   发表时间:2012-03-16   最后修改:2012-03-16
希望有人能解释下下面程序出来的值,一共三个类

public class Constants {

    public static int syncIntValue = 0;
    
    public static int syncIntValueExecCount = 0;
    
    
}


public class MyRun implements Runnable {
    
    private String name;
    
    public MyRun(String name) {
        this.name = name;
    }
    
    public void run() {
       printSyncIntValue();
    }
     
    public synchronized void printSyncIntValue() {
        Constants.syncIntValue++;
        Constants.syncIntValue++;

        synchronized ("xxxx2") {
            Constants.syncIntValueExecCount++; 
        }
    }
}

  
public class Test {

    public static void main(String[] args) {
       
             
        for (int i = 0; i < 5486; i++) {
            Thread t = new Thread(new MyRun("syncIntValue"));
            t.start();
        }
      
        if (Constants.syncIntValueExecCount != 5486) {
            System.out.println("Constants.syncIntValueExecCount=" + Constants.syncIntValueExecCount);
        }
     
        // 10972
        System.out.println("Constants.syncIntValue=" + Constants.syncIntValue); 

    }
}


在输出的结果值里面Constants.syncIntValue=10970,为什么不是10972啊,那个方法我用了synchronized来同步,而且Constants.syncIntValueExecCount =5486,能表示我在输出Constants.syncIntValue值的时候所有的线程都已执行完毕。真心求答案

我知道原因了,谢谢
   发表时间:2012-03-16  
很可能是你起的线程还没有执行结束,而你的主线程已经要打印结果了。

0 请登录后投票
   发表时间:2012-03-16  
new了5486个MyRun,就有5486把锁,printSyncIntValue用了5486个锁,有啥用啊?

将printSyncIntValue变成static试试
0 请登录后投票
   发表时间:2012-03-16  
你的主线程没有同步访问Constants 两个静态变量的方法,所以不是线程安全的。主线程有可能看不到其他线程修改的结果。并且,理论上打印出来的值有可能是任何小于10972 的数。
0 请登录后投票
   发表时间:2012-03-19  
kevin2003sk 写道
很可能是你起的线程还没有执行结束,而你的主线程已经要打印结果了。




同解
可以在主线程在打印前使所有子线程join。
0 请登录后投票
   发表时间:2012-03-19  
    public synchronized void printSyncIntValue() { 
        Constants.syncIntValue++; 
        Constants.syncIntValue++; 
 
        synchronized ("xxxx2") { 
            Constants.syncIntValueExecCount++;  
        } 
    } 

外面的已经锁掉了,里面的同步代码块还有意义么 ?
况且第二个传进去的“xxxx2”,但是你代码块里面锁的却跟xxxx2没有关系的东西 。
这是理解,可能有错误啊
0 请登录后投票
   发表时间:2012-03-19  
楼上两个原因都有:
  每个实例一把锁,相当于没锁。(对外层的sychronized来说)。
  主线程打印的时候,子线程未必执行已经完。
0 请登录后投票
   发表时间:2012-03-19  
"xxxx2" 没有起到同步的作用吧。 线程要竞争同一资源(也就是同一对象),锁就应该在一个资源上呀……
0 请登录后投票
   发表时间:2012-03-19  
lovexp2010 写道
"xxxx2" 没有起到同步的作用吧。 线程要竞争同一资源(也就是同一对象),锁就应该在一个资源上呀……

String对象会缓存起来的
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics