[英]Threading in Java: How to lock an object?
以下函数在其自己的线程中执行:
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);
}
}
当执行到达serverAddr.wait(60000)
行时,它会抛出异常:
java.lang.IllegalMonitorStateException: object not locked by thread before wait()
有谁知道如何锁定对象或函数以防止并发? 我试图添加一个Lock对象:
private final Lock lock = new ReentrantLock();
和线
boolean locked = lock.tryLock();
在功能的开头但它没有用。
为了在对象上调用wait(),您必须在该对象上保持同步锁(尽管在线程等待时实际释放了锁):
synchronized (serverAddr) {
serverAddr.wait();
}
我不得不承认,在这种情况下你为什么要这样做会让我感到困惑......
也许你正在寻找的方法是Thread.sleep(长) ? 此方法将在恢复之前等待 (如停止执行线程)指定的时间(以毫秒为单位)。
object.wait(long) (这是你正在使用的)做了一些完全不同的事情。 它等待来自另一个线程的另一个对象通知它(即:发送一种唤醒消息),并且最多等待指定的毫秒数。 鉴于您发布的代码,我非常怀疑这是您真正想要的。
如果Thread.sleep()不是您想要的,那么您应该使用其他海报提到的synchronized块。
当我看到这种代码时,我总是畏缩。 帮自己一个忙,看看java.util.concurrent
包。
要避免该错误消息,请使用synchronized关键字:
synchronized(serverAddr){
serverAddr.wait(60000);
}
以上是正确的。 您可以使用同步的代码块。 或者你可以创建他们称之为互斥的东西。 互斥体实际上可以是任何对象。 很多人只是将Object本身用作互斥体。 然后你可以锁定互斥锁。 任何想要访问的线程都必须等待持有互斥锁的线程才能释放它。
Apocalisp也提出了一个建议。 我还建议您查看java.util.concurrent包。
下面的代码应该工作。
private final ReentrantLock lock = new ReentrantLock();
lock.lock(); // block until condition holds
try {
serverAddr.wait(60000);
} finally {
lock.unlock()
}
}
有关更多详细信息,请参阅此文档页面 。
public void lock()
获得锁。
如果锁没有被另一个线程保持并获得锁定并立即返回,则将锁定保持计数设置为1。
如果当前线程已经保持锁定,则保持计数增加1并且该方法立即返回。
如果锁由另一个线程保持,那么当前线程将被禁用以进行线程调度,并且在获取锁定之前处于休眠状态,此时锁定保持计数设置为1
请参阅此SE问题以了解lock
synchronization
的优点:
通常,当您在Java中使用多线程程序时,您需要使用synchronized(key-word)来锁定共享变量,然后在任何时候只需一个线程就可以访问共享内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.