每当调用并返回Object类中的wait,notify和notifyAll方法时,我都会尝试打印到控制台。为此,我创建了一个包装类,它代表lock对象调用wait,notify和notifyAll方法。然后我使用包装器上的方法而不是wait,notify和notifyAll。这是我最好的尝试,
Thread One运行Runnable r1
Runnable r1 = new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
// wait not wrapped in while loop for brevity.
//lock.wait();
lock.objWrapper.waitNew(); // Use the wrapper method instead of wait()
} catch (InterruptedException e) {}
}
}
};
线程2运行Runnable r2
Runnable r2 = new Runnable() {
@Override
public void run() {
synchronized(lock) {
//lock.notifyAll();
lock.objWrapper.notifyAllNew(); // Use the wrapper method instead of notifyAll()
}
}
};
类Lock被定义为,
public class Lock {
ObjWrapper objWrapper = new ObjWrapper(this);
// shared data here
}
Lock lock = new Lock();
包装类定义为,
public class ObjWrapper {
Object obj = null;
ObjWrapper(Object obj) {
System.out.println("New Object wrapper created: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
this.obj = obj;
}
public void waitNew() throws InterruptedException {
System.out.println("Entering Object::wait: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
obj.wait();
System.out.println("Exiting Object::wait: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
}
public void notifyNew() {
System.out.println("Entering Object::notify: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
obj.notify();
System.out.println("Exiting Object::notify: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
}
public void notifyAllNew() {
System.out.println("Entering Object::notifyAll: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
obj.notifyAll();
System.out.println("Exiting Object::notifyAll: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
}
}
最后,使用
启动线程 Thread t1 = new Thread(r1);
t1.setName("Thread One");
t1.start();
Thread t2 = new Thread(r2);
t2.setName("Thread Two");
t2.start();
控制台上的输出,
New Object wrapper created: Thread: Thread[main,5,main] at time: 2017-03-19T22:48:28.771Z
Entering Object::wait: Thread: Thread[Thread One,5,main] at time: 2017-03-19T22:48:28.844Z
Entering Object::notifyAll: Thread: Thread[Thread Two,5,main] at time: 2017-03-19T22:48:31.845Z
Exiting Object::notifyAll: Thread: Thread[Thread Two,5,main] at time: 2017-03-19T22:48:31.845Z
Exiting Object::wait: Thread: Thread[Thread One,5,main] at time: 2017-03-19T22:48:31.845Z
我的问题是,
编辑:
我不是在寻找更好的方法来锁定物体。更好的方法是专门记录wait()
,notify()
和notifyAll()
方法的调用。
答案 0 :(得分:0)
关于问题1,我宁愿继承ReentrantLock和Condition,然后覆盖信号和等待方法,因为采用这种方法,无论如何,你失去了在方法上使用关键字synchronized的可能性。
关于问题2,我在这里可以看到的主要边缘情况是你受intrinsic lock和内在条件队列的约束。我认为一个很大的警告是,如果你想使用ReentrantLock和/或Condition,你将不得不编写新的包装器(这可能不是直截了当的),冒着引入更多复杂性的风险,还有更多问题。
现在您可能已经意识到,我建议坚持使用更高级别的API,即Latches,Semaphores,Barriers,ConcurrentCollection等等,并尽可能远离低级别的线程管理,因为它很快就会变得棘手。