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(Collection
ThreadPoolExecutor
不会将任务添加到其工作队列中。它会将任务添加到其工作队列中,如果不接受,则将任务传递给配置的。默认情况下,这是,这会导致引发
RejectedExecutionException

将永远不会调用自定义队列中的
add
方法


如果您想跟踪飞行中任务数量的变化,我建议重写执行器本身的
beforecute
afterecute
方法。活动任务的数量可以从
getActiveCount

获得是的,我认为您需要
synchronized
方法,使其成为线程fe,因为您有类作用域成员(变量和对象)AFAIK,这不是线程安全的。我的建议是永远不要对任何并发数据结构进行子类化,因为它通常会导致并发问题。此外,让队列负责发出警报似乎超出了它的预期作用域(记住它只是一个数据结构)。正如teppic所建议的,您应该将
ThreadPoolExecutor
子类化,并使用
beforeExecute
afterExecute
来实现您的目标。旁注:所有
public
属性都非常可怕!维护这个类很有趣。-)谢谢,我已经覆盖了offer()方法。它也可以工作。我是否需要为这些重写的方法添加syncronized块。