如何在java中使用synchronized

如何在java中使用synchronized,java,multithreading,synchronized,Java,Multithreading,Synchronized,我希望我可以理解地描述这种情况。 我想启动一些线程,所有线程都将执行一个同步方法。考虑在这个方法中第一个线程检查变量的值,然后在检查后释放锁,然后第二个线程调用相同的函数。但是第一个线程将(在一些ms之后)修改另一个类中的这个变量,但是第二个线程将(可能)在第一个线程更改它之前检查这个变量。在第二个线程检查值之前,如何强制第二个线程等待(无睡眠),直到第一个线程完成并更改变量?第一个是否可以发送一些信号,如“变量已更改,您现在可以检查它” 现在我尝试在代码中编写以下内容:线程启动所有线程都执行此

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

现在我尝试在代码中编写以下内容:线程启动所有线程都执行此运行:

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;
    }
}
以及:


您所描述的问题听起来好像可以从Java同步原语中获益,如
Object.wait
Object.notify

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

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

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


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

我正在尝试使用wait()和notify()因为小时,但我没有得到正确的结果,我总是得到竞赛条件,我应该在我的代码中使用它吗?此代码看起来不正确。
EatingRoom
类有一个
count
类型的成员变量
Set
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..

}