【问题标题】:Java multithreading with wait and notify带有等待和通知的 Java 多线程
【发布时间】:2013-05-28 05:34:14
【问题描述】:

我有这段代码

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,然后让每个人都等待。

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

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

谢谢

【问题讨论】:

  • @AmitD 你的意思是volatiletransient 只是表示不应在实现 Serializable 的类中序列化字段。
  • 是的。我想更正自己使用提到的 volatile
  • @OP,请尝试使用变量命名约定(名称应以小写字母开头),阅读代码时会混淆

标签: java multithreading wait notify


【解决方案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.

【讨论】:

  • “既然你正在调用wait()”是什么意思?如果我不使用 wait 并且只有 2 个带两个线程的同步方法并以 true 和 false 再次执行它们,这两种方法是否不可能一起执行?至于第二个答案,有什么办法可以避免这种情况吗?谢谢。
  • 除非你调用 wait 2 线程不能执行同一个类实例的两个不同同步方法。原因是如果一个类的实例有锁,其他线程不能访问同一实例的任何其他同步方法,除非第一个调用 wait(),在这种情况下 thread1 释放锁但仍然停留在第一个同步方法中。
【解决方案2】:

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

如果您希望两个不同的线程同时访问这些同步方法,那么这两个线程应该对类的 2 个不同对象进行操作。

【讨论】:

    【解决方案3】:

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

    正如我所说,一个方法一次只能由一个线程执行,除非执行线程通过调用wait 方法释放lock,而其他线程获取lock 并执行其他synchronized 方法,这使您的这两种说法可能

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 2020-08-31
      • 2018-05-14
      • 2013-02-20
      • 1970-01-01
      相关资源
      最近更新 更多