Java 自定义LinkedBlockingQueue死锁
我一直在Java 自定义LinkedBlockingQueue死锁,java,deadlock,blockingqueue,Java,Deadlock,Blockingqueue,我一直在ThreadExecutorPool中使用自定义blockingqueue,但有时任务工作者不接受任务,而dispacher线程不将新任务放入队列 我想知道以下自定义阻塞队列实现会导致死锁。这个代码有什么错误吗? 对于add()和take()方法,最好使用和synchronized块 import java.util.Collection; import java.util.concurrent.LinkedBlockingQueue; import org.apache.log4j.
ThreadExecutorPool
中使用自定义blockingqueue,但有时任务工作者不接受任务,而dispacher线程不将新任务放入队列
我想知道以下自定义阻塞队列实现会导致死锁。这个代码有什么错误吗?
对于add()
和take()
方法,最好使用和synchronized
块
import java.util.Collection;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.log4j.Logger;
import com.ttech.utils.alarm.Alarm;
import com.ttech.utils.alarm.AlarmInterface;
import com.ttech.utils.counter.Counter;
import com.ttech.utils.counter.SNMPAgent;
public class WorkerQueue<E> extends LinkedBlockingQueue<E> {
private static final long serialVersionUID = 1L;
public Integer lowThreshold;
public Integer highThreshold;
public Integer capacity;
public String name;
public String type;
public Counter counter = null;
public boolean writeAlarmLog;
public static final Logger logger = Logger.getLogger(WorkerQueue.class);
public static Alarm HighThresholdAlarm = null;
public static Alarm CapacityAlarm = null;
// Check the size here and clear capacity and high threshold alarms in case
public E take() throws InterruptedException {
E data = super.take();
counter.setNewValue(super.size());
if (super.size() == lowThreshold) {
if(!this.writeAlarmLog) {
HighThresholdAlarm.clear(name);
CapacityAlarm.clear(name);
} else {
HighThresholdAlarm.clearLog(name, "Queue High Threshold");
CapacityAlarm.clearLog(name, "Queue Capacity Overload");
}
}
return data;
}
public E poll() {
E data = super.poll();
counter.setNewValue(super.size());
if (super.size() == lowThreshold) {
if(!this.writeAlarmLog) {
HighThresholdAlarm.clear(name);
CapacityAlarm.clear(name);
} else {
HighThresholdAlarm.clearLog(name, "Queue High Threshold");
CapacityAlarm.clearLog(name, "Queue Capacity Overload");
}
}
return data;
}
public int drainTo(Collection<? super E> c, int maxElements){
int size = super.drainTo(c,maxElements);
counter.setNewValue(super.size());
return size;
}
// During adding the data to queue check capacity and high threshold raise alarm in case
public boolean add(E data) {
Boolean rc = true;
if (capacity > 0) {
if (this.size() >= capacity) {
logger.error("Queue " + name + " is over capacity");
if(!this.writeAlarmLog)
CapacityAlarm.raise(name);
else
CapacityAlarm.raiseLog(AlarmInterface.AS_CRITICAL, name, "Queue Capacity Overload");
return false;
}
}
if (!super.add(data)) {
logger.error("Cannot add data to queue:" + name);
rc = false;
} else {
counter.setNewValue(super.size());
}
if (highThreshold == super.size()) {
if(!this.writeAlarmLog)
HighThresholdAlarm.raise(name);
else
HighThresholdAlarm.raiseLog(AlarmInterface.AS_CRITICAL, name, "Queue High Threshold");
}
return rc;
}
}
import java.util.Collection;
导入java.util.concurrent.LinkedBlockingQueue;
导入org.apache.log4j.Logger;
导入com.ttech.utils.alarm.alarm;
导入com.ttech.utils.alarm.AlarmInterface;
导入com.ttech.utils.counter.counter;
导入com.ttech.utils.counter.SNMPAgent;
公共类WorkerQueue扩展LinkedBlockingQueue{
私有静态最终长serialVersionUID=1L;
公共整数阈值;
公共整数阈值;
公共综合能力;
公共字符串名称;
公共字符串类型;
公共计数器=空;
公共布尔写ARMLOG;
publicstaticfinallogger=Logger.getLogger(WorkerQueue.class);
公共静态报警HighThresholdAlarm=null;
公共静态报警电容Arm=null;
//检查此处的大小,并清除容量和高阈值警报,以防
public E take()抛出InterruptedException{
E data=super.take();
counter.setNewValue(super.size());
如果(super.size()==低阈值){
如果(!this.writeAlarmLog){
HighThresholdAlarm.clear(名称);
电容臂。清除(名称);
}否则{
clearLog(名称,“队列高阈值”);
clearLog(名称,“队列容量过载”);
}
}
返回数据;
}
公众电子投票{
E data=super.poll();
counter.setNewValue(super.size());
if(super.size()==低阈值){
如果(!this.writeAlarmLog){
HighThresholdAlarm.clear(名称);
电容臂。清除(名称);
}否则{
clearLog(名称,“队列高阈值”);
clearLog(名称,“队列容量过载”);
}
}
返回数据;
}
public int drainTo(CollectionThreadPoolExecutor
不会将任务添加到其工作队列中。它会将任务添加到其工作队列中,如果不接受,则将任务传递给配置的。默认情况下,这是,这会导致引发RejectedExecutionException
将永远不会调用自定义队列中的add
方法
如果您想跟踪飞行中任务数量的变化,我建议重写执行器本身的beforecute
或afterecute
方法。活动任务的数量可以从getActiveCount
获得是的,我认为您需要synchronized
方法,使其成为线程fe,因为您有类作用域成员(变量和对象)AFAIK,这不是线程安全的。我的建议是永远不要对任何并发数据结构进行子类化,因为它通常会导致并发问题。此外,让队列负责发出警报似乎超出了它的预期作用域(记住它只是一个数据结构)。正如teppic所建议的,您应该将ThreadPoolExecutor
子类化,并使用beforeExecute
和afterExecute
来实现您的目标。旁注:所有public
属性都非常可怕!维护这个类很有趣。-)谢谢,我已经覆盖了offer()方法。它也可以工作。我是否需要为这些重写的方法添加syncronized块。