带有等待和通知的Java多线程

时间:2013-05-28 05:34:14

标签: java multithreading wait notify

我有这段代码

public MultiThreadedSum(ArrayBuffer ArrayBufferInst)
{
    this.ArrayBufferInst = ArrayBufferInst;
    Sum = 0;
    Flag = false;
    StopFlag = false;
}

public synchronized void Sum2Elements()
{

    while(Flag)
    {
        try {wait();}
        catch (InterruptedException e){}
    }

    Flag = true;

    if (StopFlag)
    {
        notifyAll();
        return;
    }

    System.out.println("Removing and adding 2 elements.");

    Sum = ArrayBufferInst.Sum2Elements();

    notifyAll();
}

public synchronized void InsertElement()
{

    while(!Flag)
    {
        try {wait();}
        catch (InterruptedException e){}
    }

    Flag = false;

    if (StopFlag)
    {
        notifyAll();
        return;
    }

    System.out.println("Inserting the sum.");

    ArrayBufferInst.InsertElement(Sum);

    if (ArrayBufferInst.RetunrSize() == 1)
    {
        StopFlag = true;
    }

    System.out.println(ArrayBufferInst);

    notifyAll();
}

正如您所看到的,我首先将Flag设置为false,这样其中一个线程就可以进入Sum2Elements方法并将其更改为true,然后让每个人等待。

我知道在同步代码中,只有一个线程可以做它的事情,在这里我有两个同步的方法,这是否意味着2个线程试图在每个notifyall之后执行这个方法?

如果是这样,一个线程不可能进入Sum2Elements,在另一个线程进入InsertElement之前将标志更改为true,并跳过while循环吗?

由于

3 个答案:

答案 0 :(得分:1)

只有一个线程可以保持对象的锁定。然后它只是那个可以在该对象上输入同步方法的线程。

然而,线程可以通过调用Object.wait()来释放锁而不从方法返回。

所以你的代码看起来不错!

does it mean that 2 threads are trying to conduct this methods after each notifyall? 
Ans : It is very much possible for two threads to be in two of your synchronized methods since you are calling wait().

is it not possible for one thread to enter Sum2Elements, change the flag to true before the other thread enters InsertElement, and by that skipping the while loop?
Ans : Yes this is possible again for the same reason specified above.

答案 1 :(得分:0)

Only one thread can execute one of two method at a time because both are synchronized though order is undefined

正如我所说,一个方法一次只能由一个线程执行,除非执行线程通过调用lock方法释放wait,而其他线程获取lock并执行其他{ {1}}方法,使您的语句成为可能

答案 2 :(得分:0)

锁定是在类和对象的对象上获得的。不是任何特定的同步方法。 这两种方法都是实例方法。因此,如果其中一个线程输入了对象的任何同步方法,A说,那么任何其他线程都无法输入该对象的任何同步方法,直到正在运行的线程不调用notifyAll()方法。在那个阶段,所有等待的线程竞争变得活跃,但它依赖于线程调度程序来选择一个活跃的线程。

如果您希望两个不同的线程同时访问这些同步方法,则2个线程应该在该类的2个不同对象上运行。