感谢您帮助理解"并发示例":http: //forums.sun.com/thread.jspa?threadID = 735386
Qute开始:
public synchronized void enqueue(T obj) {
// do addition to internal list and then...
this.notify();
}
public synchronized T dequeue() {
while (this.size()==0) {
this.wait();
}
return // something from the queue
}
Run Code Online (Sandbox Code Playgroud)
报价结束:
我的问题是:为什么这段代码有效?
=>当我同步像" public synchronized"=> 这样的方法时,我同步"对象的实例==> this".但是在上面的例子中:
呼叫"出列"我将打开"锁定/监视器" this
现在我在出队方法.由于列表为零,调用线程将为" waited"
this:所以我永远不会有可能称之为"enequeue",因为我不会得到this"锁定".Backround:我有完全相同的问题:我有一些连接池(连接列表),如果检查所有连接,需要阻止.如果大小超过限制或为零,将List同步到阻止的正确方法是什么?
非常感谢你
延
我有一个JPanel类,它使用"implements runnable"启动另一个线程.然后,这个其他线程将在各个点调用JPanel类中的一个方法,然后这样做将需要等待用户输入.我试图像这样实现它:
JPanel类中的方法由需要等待的其他线程调用:
public void methodToWait()
{
while(conditionIsMet)
{
try
{
wait();
}
catch
{
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
JPanel类中的方法,用于通知用户输入的等待:
public void mouseClicked(MouseEvent event)
{
notifyAll();
}
Run Code Online (Sandbox Code Playgroud)
但是,在运行应用程序时,它会在调用wait时抛出"java.lang.IllegalMonitorStateException",为什么要执行此操作以及如何解决此问题?
当一个对象需要同步时,IDE会抱怨它是否设置为非final(因为它的引用不是持久的):
private static Object myTable;
....
synchronized(myTable){ //IDE complains!
//access myTable here...
}
Run Code Online (Sandbox Code Playgroud)
众所周知,如果持有锁的线程改变了非最终对象的引用,IDE会抱怨阻止另一个线程进入受保护的块.
但是同步对象的引用是否也可以由另一个线程B更改,而线程A保持同一对象的锁定?
我有基于我在网上找到的示例的示例代码来说明如何使用wait()和notify().让我在代码示例前面加上Java教科书所做的以下语句wait和notify.
线程不能在对象上调用wait或notify方法,除非它拥有该对象的锁定
现在看看这段代码和输出:
public class ThreadTester
{
public class Message {
private String msg;
public Message(String str){ this.msg=str;}
public String getMsg() { return msg; }
public void setMsg(String str) { this.msg=str;}
}
public class Waiter implements Runnable{
private Message msg;
public Waiter(Message m){
this.msg = m;
}
public void run() {
String name = Thread.currentThread().getName();
synchronized (msg) {
try{
System.out.println(name + " acquired lock to msg object. waiting to get notified");
msg.wait(); …Run Code Online (Sandbox Code Playgroud) 我最近发现使用synchronized不会阻止任何死锁.
例如,在此代码中:
ArrayList <Job> task;
...
public void do(Job job){
synchronized(tasks){
tasks.add(job);
}
synchronized(this){
notify();
}
}
public void run(){
while(true){
for (int = 0;i<tasks.size();i++){
synchronized(tasks){
Job job = tasks.get(i);
}
//do some job here...
}
synchronized(this){
wait(); //lock will be lost...
notifier = false; //lock will be acquired again after notify()
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,问题是什么?好吧,如果正在运行的线程没有等待,他将不会看到任何通知(即notify()调用),因此他可能会遇到死锁而无法处理他收到的任务!(或者他可能太晚处理它们......)
因此我实现了这段代码:
private volatile boolean notifier = false;
ArrayList <Job> task;
...
public void do(Job job){
synchronized(tasks){
tasks.add(job);
}
synchronized(this){
notifier = true;
notify();
} …Run Code Online (Sandbox Code Playgroud)