多线程问题:notify()后线程不是每次都会执行
一个队列,两个线程,一个线程负责往队列里add,另一个从队列removeFirst()队列空时就wait(),add一个后就notify(),队列size超过100就丢弃add的对象
大多情况下执行没问题,但是总有一段时间只执行add,不执行removeFirst(),就算每次add后都执行notify()也不行
把队列size给添加到100,造成数据丢弃
请大家帮忙分析下为什么notify后不执行removeFirst(),大致的代码如下
public void SendMsg(byte[] msg) {
byte[] newmsg;
newmsg = msg.clone();
synchronized (m_out_q) {
// 不能过多。注意,过多时,不是等待,而是丢弃
if (m_out_q.size() > = m_maxsize)
return;
m_out_q.addLast(newmsg);
if (m_out_q.size() > = 1) {
m_out_q.notify();
}
}
}
public void run() {
byte[] thismsg = null;
while (true) {
synchronized (m_out_q) {
while (m_out_q.isEmpty()) {
try {
m_out_q.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
thismsg = m_out_q.removeFirst();
} // end of synchronized
UDPService.sendMessage(thismsg);
}
}
--------------------编程问答-------------------- 总有一段时间只执行add,不执行removeFirst(),这就对了。
两线程并不是真正意义上的同时运行,两线程以乱序在执行,多线程切换时不能保证也无法预知哪一线程何时获得CPU等资源而执行。此所谓风水轮流转。
--------------------编程问答-------------------- +1 --------------------编程问答-------------------- 你上面的code
if (m_out_q.size() > = m_maxsize)
return;
改成:
if (m_out_q.size() > = m_maxsize){
m_out_q.notify();
return;
}
测试下. --------------------编程问答-------------------- 总有一段时间只执行add,不执行removeFirst(),
还有一原因,LZ对m_out_q的操作不是线程安全的。没对m_out_q.removeFirst()同步。
--------------------编程问答-------------------- 咱们先来看SendMsg(byte[] msg) 方法。LZ只用了m_out_q.notify(); 而没有m_out_q.wait()方法。这会导致一个状况就是这个线程根本不会停下来。一直运行。一直运行就会长时间的站有锁。而run() 方法里面却m_out_q.wait();导致好不容易拿来的锁一下子就释放了,线程又进入休眠状态了。直到没准什么时候会被唤醒。所以会导致LZ说的这种现象。notify和wait应该都是配对使用的。 --------------------编程问答--------------------
public void run() {
byte[] thismsg = null;
while (true) {
synchronized (m_out_q) {
while (m_out_q.isEmpty()) {
try {
m_out_q.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
thismsg = m_out_q.removeFirst(); // 对m_out_q同步
}
} // end of synchronized
UDPService.sendMessage(thismsg);
}
}
+1
当队列达到最大的时候,没有通知另一个删除线程,这样删除线程就一直处于等待
而追加线程每次if (m_out_q.size() > = m_maxsize){在这里都直接返回,删除线程就一直不会被唤醒
--------------------编程问答--------------------
+1
补充:Java , Java SE