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