2014-10-18 52 views
2

我知道那个问题“两个同步方法是否同时执行”之前已经问过,答案是“否。只有一个线程可以保存该对象的锁,然后它只是那个可以进入同步方法的线程那个对象。“ 但是,如果其真正的话,请帮我理解下面的代码输出:类有2个同步方法..当一个线程在第二个方法里面时另一个线程可以进入第一个方法吗?

public class SynchronizationMistake { 

public int count; 

public synchronized int getCount() 
{ 
    return count; 
} 
public synchronized String incrementCount() 
{ 
    count++; 
    return""; 
} 

public static void main (String args[]) 
{ 
    SynchronizationMistake syn = new SynchronizationMistake(); 
    Thread first = new Thread(syn.new readIncrementCount(syn),"First"); 
    Thread second = new Thread(syn.new readIncrementCount(syn), "Second"); 
    Thread third = new Thread(syn.new readIncrementCount(syn), "Third"); 

    first.start(); 
    second.start(); 
    third.start(); 

} 
private class readIncrementCount implements Runnable 
{ 

    SynchronizationMistake syn; 
    readIncrementCount(SynchronizationMistake syn) 
    { 
     this.syn = syn; 
    } 
    @Override 
    public void run() { 

     System.out.println("I am "+Thread.currentThread().getName()+".Count is "+ syn.getCount()); 
     System.out.println("I am "+Thread.currentThread().getName()+".Incrementing count now"+syn.incrementCount()); 
     System.out.println("I am "+Thread.currentThread().getName()+". After Increment Count is "+ syn.getCount()); 


    } 

} 

}

Output is : 
I am First.Count is 0 
I am First.Incrementing count now 
I am First. After Increment Count is 1 
I am Third.Count is 0 
I am Second.Count is 0 
I am Third.Incrementing count now 
I am Second.Incrementing count now 
I am Third. After Increment Count is 3 
I am Second. After Increment Count is 3 

输出变化我每次运行这个程序的时间。我怀疑当第二/第三线程得到CPU为什么它没有读'count'为1(由第一个线程更新)?换句话说,当第一个线程锁定'syn'并将count更新为1时,第二个/第三个线程如何设法进入'getCount'方法。

回答

5

语句System.out.println("I am "+Thread.currentThread().getName()+".Count is "+ syn.getCount());不是以原子方式执行的。部分syn.getCount()可以在println之前执行。这也似乎发生在你的例子中。所有线程首先执行syn.getCount(),那时计数仍为0,然后才执行其余的操作。

0

您发布的这个特定执行会发生什么情况,即所有三个线程都读取的计数器值为零,但是线程一有机会在其他人之前完成其所有输出,即对计数器的访问被正确同步,但后来的打印由于输出缓冲而显示较旧的值。

尝试在第一个线程启动后进行睡眠,这应该不太可能再次发生。

0

正如Henry提到的,所有线程都可以先执行syn.getCount(),然后执行syn.incrementCount。我已经修改了你的代码稍微改变println语句赋予更好的画面......

public class SynchronizationMistake { 

public int count; 

public synchronized int getCount() 
{ 
    return count; 
} 

public synchronized String incrementCount() { 

    System.out.println("I am " + Thread.currentThread().getName() + ", incrementing the count from " + count); 
    count++; 
    System.out.println("I am " + Thread.currentThread().getName() + ", incremented the count to " + count); 
    return""; 
} 

public static void main (String args[]) 
{ 
    SynchronizationMistake syn = new SynchronizationMistake(); 
    Thread first = new Thread(syn.new readIncrementCount(syn),"First"); 
    Thread second = new Thread(syn.new readIncrementCount(syn), "Second"); 
    Thread third = new Thread(syn.new readIncrementCount(syn), "Third"); 

    first.start(); 
    second.start(); 
    third.start(); 

} 
private class readIncrementCount implements Runnable 
{ 

    SynchronizationMistake syn; 
    readIncrementCount(SynchronizationMistake syn) 
    { 
     this.syn = syn; 
    } 
    @Override 
    public void run() { 

     System.out.println("Current count is " + syn.getCount()); 
     System.out.println(syn.incrementCount()); 
     System.out.println("Current count is " + syn.getCount()); 
    } 

} 

} 

不同的输出可以如下......

输出#1:

Current count is 0 
I am Second, incrementing the count from 0 
Current count is 0 
I am Second, incremented the count to 1 

Current count is 1 
I am First, incrementing the count from 1 
I am First, incremented the count to 2 

Current count is 2 
Current count is 2 
I am Third, incrementing the count from 2 
I am Third, incremented the count to 3 

Current count is 3 

输出#2:

Current count is 0 
Current count is 0 
Current count is 0 
I am Second, incrementing the count from 0 
I am Second, incremented the count to 1 

I am Third, incrementing the count from 1 
I am Third, incremented the count to 2 

I am First, incrementing the count from 2 
I am First, incremented the count to 3 

Current count is 3 
Current count is 3 
Current count is 3 
相关问题