【问题标题】:How to use synchronized in java如何在java中使用同步
【发布时间】:2018-05-12 18:33:28
【问题描述】:

我希望我可以理解地描述这种情况。 我想启动一些线程,它们都将执行一个同步方法。考虑第一个线程在此方法中检查变量的值,然后在检查后释放锁。然后第二个线程调用相同的函数。但是第一个线程将(在几毫秒后)修改这个在另一个类中的变量,但第二个线程将(可能)在第一个更改变量之前检查该变量。如何强制第二个线程等待(不休眠),直到第一个线程完成并在第二个线程检查值之前更改变量?第一个可以发送一些信号,例如“变量已更改,您现在可以检查一下”吗?

现在我尝试在代码中写这个:线程启动全部执行此操作:

abstract class Animal {
protected House house;
    abstract boolean eating();
    @Override
    public void run() {
        try {
            while(!Thread.interrupted()) {
                if(eating()) {
                   goEat();//here house.eatingRoom.count will be changed
                   Thread.sleep(1000);
                    goback();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

他们都访问这个方法:

class Cat extends Animal {

@Override
   synchronized boolean eating() {
       if (house.eatingRoom.count == 0) 
           return true;//first thread release lock and 2 thread access it but the value is not changed yet
       else
           return false;
    }
}

还有:

class EatingRoom {
    final Set<Animal> count = new HashSet<>();
    synchronized void add(Cat c) {
         count.add(c);
    }
}

完成:

public class House extends Thread {

    final EatingRoom eatingRoom = new EatingRoom();
//start all threads here so run in Animal class is executed..

}

【问题讨论】:

  • 这段代码看起来不正确。 EatingRoom 类有一个 count 类型的成员变量 Set&lt;Animal&gt; 并且您的 Cat 类具有以下逻辑 if (house.eatingRoom.count == 0)idownvotedbecau.se/nomcve

标签: java multithreading synchronized


【解决方案1】:

您所描述的问题听起来像是您可以从 Object.waitObject.notify 等 Java 同步原语中受益。

拥有给定对象的锁/监视器的线程(例如通过使用synchronized 关键字)可以调用wait,而不是像在while(!Thread.interrupted()) 中那样以忙碌/等待模式循环和休眠可能会浪费很多 CPU 周期。

一旦线程进入等待状态,它将释放它持有的锁,这允许另一个线程获取相同的锁并可能更改某些状态,然后通过 notify/notifyAll 通知一个或多个等待线程。

请注意,必须小心确保以相同的顺序获取和释放锁,以帮助避免在涉及多个锁时出现死锁情况。还可以考虑在等待时使用超时,以确保您的线程不会无限期地等待可能永远不会出现的条件。如果在您调用 notify 时有许多等待线程,请注意您可能不知道将调度哪个线程,但您可以设置公平策略来帮助影响这一点。

根据您的代码结构,您可以通过使用一些更高级别的 API(例如 https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.htmlvolatile 等关键字用于包含共享可变状态的变量(就像您要等待的条件一样,以确保在“发生在之前”关系中的后续读取中观察到写入结果。

【讨论】:

  • 我尝试使用 wait() 和 notify() 从几个小时开始,但我没有得到正确的结果,我总是得到竞争条件,我应该在我的代码中哪里使用它?
猜你喜欢
  • 2017-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多