简体   繁体   English

类具有2个同步方法。.当一个线程位于第二个方法内时,另一个线程可以进入第一个方法吗?

[英]Class has 2 synchronized methods..when a thread is inside second method can another thread enter into first method?

I know that question "Do two synchronized methods execute simultaneously" have been asked before and the answer given was " No. Only one thread can hold the lock of the object. And then it's only that thread that can enter the synchronized methods on that object." 我知道之前曾问过“同时执行两个同步方法”问题,给出的答案是“否。只有一个线程可以持有对象的锁。然后只有那个线程才能在该对象上输入同步方法。 “。 However, if its true then please help me understand the output of below code : 但是,如果它是真的,那么请帮助我理解以下代码的输出:

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

Output varies every time I run this program. 每次我运行此程序时,输出都会变化。 My doubt is when Second/Third thread got the CPU why it didn't read 'count' as 1 ( updated by first thread)? 我的疑问是当第二/第三线程获得CPU时,为什么它没有将“ count”读为1(由第一线程更新)? in other words while First thread had lock on 'syn' and was updating the count to 1 how did Second/Third thread managed to enter into 'getCount'method. 换句话说,当第一个线程锁定了“ syn”并正在将计数更新为1时,第二个/第三个线程如何设法进入“ getCount”方法。

The statement System.out.println("I am "+Thread.currentThread().getName()+".Count is "+ syn.getCount()); 语句System.out.println("I am "+Thread.currentThread().getName()+".Count is "+ syn.getCount()); is not executed in an atomic way. 不是以原子方式执行的。 The part syn.getCount() can be executed way before the println . syn.getCount()部分可以在println之前执行。 This also seems to happen in your example. 您的示例中似乎也发生了这种情况。 All the threads do the syn.getCount() first, the count is still 0 at that time, and only then execute the rest. 所有线程首先执行syn.getCount() ,当时计数仍为0,然后再执行其余操作。

What happens with this particular execution you posted is that all three threads read the counter with a value of zero, but thread one has the chance to complete all of its output before others, ie access to the counter is correctly synchronized, but later prints show older values due to output buffering. 您发布的该特定执行的结果是,所有三个线程都读取值为零的计数器,但是线程一有机会在其他线程之前完成其所有输出,即,对计数器的访问已正确同步,但是稍后的打印显示较旧的值归因于输出缓冲。

Try to put a sleep after the start of the first thread and this should be less probable to happen again. 尝试在第一个线程开始之后进入睡眠状态,这种情况不太可能再次发生。

As Henry mentioned all the threads may first execute the syn.getCount(), and then execute the syn.incrementCount. 正如Henry提到的,所有线程都可以首先执行syn.getCount(),然后执行syn.incrementCount。 I have modified your code slightly to change the println statements which gives a better picture... 我已经稍微修改了您的代码以更改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());
    }

}

}

Different outputs can be as follows... 不同的输出如下所示...

Output #1 : 输出#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

Output #2 : 输出#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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当一个线程通过另一个类调用synchronized方法时会发生什么? - What happens when a synchronized method is called by a thread via another class? 从Java中同一类的另一个同步方法内部创建的新线程中调用同步方法 - Calling a synchronized method from a new thread created inside another synchronized method of the same class in Java 当其他线程正在执行此类的静态同步方法时,线程可以获取该类实例的锁吗? - Can a thread acquire a lock on a instance of a class,when other thread is executing a static synchronized method of this class? 我们可以将线程连接方法放入同步方法中吗 - can we put thread join method inside synchronized method 给一个C ++类foo,里面有一个synchronized方法。 如何保证只有一个线程访问同步方法 - Give a C++ class foo, inside, it has a synchronized method. How to guarantee the synchronized method being accessed by only one thread 一个线程可以在另一个线程完成静态初始化(类加载)之前输入静态方法吗? - Can a thread enter a static method before static initialization (class loading) is complete by another thread? 如何检查线程是否在同步块或方法中? - How can I check if a thread is inside a synchronized block or method? 同步方法中的线程锁定 - Thread locking in synchronized method 线程子类中的同步方法 - Synchronized method in thread subclass 在同步方法内的线程中同步块会发生什么? - What would happen with a synchronized block in a thread which is inside a synchronized method?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM