以下函数在其自己的线程中执行:
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
包装.