Java 中的线程:如何锁定对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/661068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Threading in Java: How to lock an object?
提问by Niko Gamulin
The following Function is executing in its own thread:
以下函数在其自己的线程中执行:
private void doSendData()
{
try {
//writeToFile(); // just a temporary location of a call
InetAddress serverAddr = InetAddress.getByName(serverAddress);
serverAddr.wait(60000);
//Log.d("TCP", "C: Connecting...");
Socket socket = new Socket(serverAddr, portNumber);
socket.setSoTimeout(3000);
try {
//Log.d("TCP", "C: Sending: '" + message + "'");
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
String message = packData();
out.println(message);
Log.d("TCP", "C: Sent.");
Log.d("TCP", "C: Done.");
connectionAvailable = true;
} catch(Exception e) {
Log.e("TCP", "S: Error", e);
connectionAvailable = false;
} finally {
socket.close();
announceNetworkAvailability(connectionAvailable);
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
announceNetworkAvailability(connectionAvailable);
}
}
When the execution reaches the line serverAddr.wait(60000)
it throws an Exception:
当执行到达该行时,serverAddr.wait(60000)
它会抛出异常:
java.lang.IllegalMonitorStateException: object not locked by thread before wait()
Does anyone know how to lock an object or a function in order to prevent the concurrency? I've tried to add a Lock object:
有谁知道如何锁定对象或函数以防止并发?我试图添加一个 Lock 对象:
private final Lock lock = new ReentrantLock();
and the line
和线
boolean locked = lock.tryLock();
at the beginning of function but it didn't work.
在函数开始时,但它不起作用。
采纳答案by Neil Coffey
In order to call wait() on an object, you have to hold the synchronized lock on that object (though the lock is actually released while the thread is waiting):
为了在对象上调用 wait(),您必须持有该对象上的同步锁(尽管该锁实际上是在线程等待时释放的):
synchronized (serverAddr) {
serverAddr.wait();
}
I have to admit that whyyou're wanting to do this baffles me in this case...
我不得不承认,在这种情况下,你为什么要这样做让我感到困惑......
回答by krosenvold
To avoid that error message, use the synchronized keyword:
为避免出现该错误消息,请使用 synchronized 关键字:
synchronized(serverAddr){
serverAddr.wait(60000);
}
回答by Apocalisp
I always cringe when I see this kind of code. Do yourself a favour and have a look at the java.util.concurrent
package.
当我看到这种代码时,我总是畏缩。帮自己一个忙,看看java.util.concurrent
包装。
回答by uriDium
The above are correct. You can use a synchronized block of code. Or you can create what they call a mutex. A mutex can actually be any object. Lots of people just use Object itself as a mutex. Then you can lock on the mutex. Any threads wanting to get access must wait for thread holding the mutex to release it.
以上都是正确的。您可以使用同步代码块。或者您可以创建他们所谓的互斥锁。互斥锁实际上可以是任何对象。很多人只是将 Object 本身用作互斥锁。然后你可以锁定互斥锁。任何想要访问的线程都必须等待持有互斥锁的线程释放它。
There was also a suggestion by Apocalisp. I would also recommend that you look at the java.util.concurrent package.
Apocalisp 也提出了一个建议。我还建议您查看 java.util.concurrent 包。
回答by LordOfThePigs
Maybe the method you are looking for is Thread.sleep(long)? This method will wait(as in stop the execution of the thread) for the specified time in milliseconds before resuming.
也许您正在寻找的方法是Thread.sleep(long)?此方法将在恢复之前等待(如停止线程的执行)指定的时间(以毫秒为单位)。
object.wait(long)(which is what you are using) does something entirely different. It waits for another object from another thread to notify it (ie: send it a sort of wakeup message), and will wait at most the specified number of milliseconds. Given the code you posted, I highly doubt this is what you really want.
object.wait(long)(这是你正在使用的)做一些完全不同的事情。它等待来自另一个线程的另一个对象通知它(即:向它发送一种唤醒消息),并且最多等待指定的毫秒数。鉴于您发布的代码,我非常怀疑这是您真正想要的。
If Thread.sleep() is not what you want, then you should use the synchronized block as mentioned by the other posters.
如果 Thread.sleep() 不是你想要的,那么你应该使用其他海报提到的同步块。
回答by Khash Nejad
In general when you have multi-threaded program in Java you need to lock the shared variable by using synchronized (key-word) then in anytime just one thread can access the shared memory.
通常,当您在 Java 中有多线程程序时,您需要使用同步(关键字)锁定共享变量,然后在任何时候只有一个线程可以访问共享内存。
回答by Ravindra babu
Below code should work.
下面的代码应该可以工作。
private final ReentrantLock lock = new ReentrantLock();
lock.lock(); // block until condition holds
try {
serverAddr.wait(60000);
} finally {
lock.unlock()
}
}
Refer to this documentation pagefor more details.
有关更多详细信息,请参阅此文档页面。
public void lock()
Acquires the lock.
Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.
获得锁。
如果其他线程没有持有锁,则获取该锁并立即返回,将锁持有计数设置为 1。
If the current thread already holds the lock then the hold count is incremented by one and the method returns immediately.
如果当前线程已经持有锁,那么持有计数加一并且该方法立即返回。
If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired, at which time the lock hold count is set to one
如果锁被另一个线程持有,那么当前线程将被禁用以进行线程调度并处于休眠状态,直到获得锁为止,此时锁持有计数设置为 1
Refer to this SE question to know the advantages of lock
over synchronization
:
请参阅此 SE 问题以了解lock
over的优点synchronization
: