Java 线程相互阻塞

Java 线程相互阻塞,java,multithreading,Java,Multithreading,我收到了文件下载请求,每次下载都在不同的线程中进行,直到超过池大小。下载完成后,处理器处理下载的项目。下载任务不会同时运行。除了task.getDownloadTask().download()或task.getProcessTask().process(即使没有同步部分)的同步部分外,还有什么原因会导致此问题 下载任务处理器 public class DownloadTaskEnqueuer { private static final BlockingQueue<Task>

我收到了文件下载请求,每次下载都在不同的线程中进行,直到超过池大小。下载完成后,处理器处理下载的项目。下载任务不会同时运行。除了task.getDownloadTask().download()或task.getProcessTask().process(即使没有同步部分)的同步部分外,还有什么原因会导致此问题

下载任务处理器

public class DownloadTaskEnqueuer {
    private static final BlockingQueue<Task> downloadQueue = new LinkedBlockingQueue<>();
    private static final BlockingQueue<Task> processQueue = new LinkedBlockingQueue<>();
    private static final ExecutorService executor = Executors.newCachedThreadPool();

    public void offer(Task task) {
        return downloadQueue.offer(task);
    }

    public void createPool(int size) {
        for (int i = 0; i < size; i++) {
            executor.execute(new DownloadTask(downloadQueue, processQueue);
            executor.execute(new ProcessTask(processQueue));
        }
    }
}

存在一些设计错误。每次编写Thread.sleep()时,都会执行忙等待模式。不建议这样做。 试试这个:

public class DownloadTaskEnqueuer implements Runnable {
private final BlockingQueue<Task>           queue       = new LinkedBlockingQueue<>();
private final LinkedList<Future<Object>>    results     = new LinkedList<>();
private final Semaphore                     lock        = new Semaphore(0);
boolean                                     isRunning   = true;
private final ExecutorService               executor;

public DownloadTaskEnqueuer(int parallismCount) {
    executor = Executors.newFixedThreadPool(parallismCount);
}

public void offer(Task task) {
    queue.offer(task);
    lock.release();
}

@Override
public void run() {
    while (isRunning) {
        lock.acquireUninterruptibly();
        Task task = queue.poll();
        Future<Object> futureResult = executor.submit(task);
        results.add(futureResult);
    }

}

public static void main(String[] args) {
    DownloadTaskEnqueuer dte = new DownloadTaskEnqueuer(10);
    Thread t = new Thread(dte);
    t.start();
}


public abstract class Task implements Callable<Object> {

abstract Object download();

abstract Object doProcess(Object downloadedObject);

@Override
public Object call() throws Exception {
    Object downloadedObject = download();
    Object processingResult = doProcess(downloadedObject);
    return processingResult;
}
public类DownloadTaskEnqueuer实现可运行{
private final BlockingQueue=新建LinkedBlockingQueue();
私有最终LinkedList结果=新建LinkedList();
私有最终信号量锁=新信号量(0);
布尔值isRunning=true;
私人最终执行人服务执行人;
公共下载任务排队器(int parallismCount){
executor=Executors.newFixedThreadPool(parallismCount);
}
公开作废要约(任务){
排队。报价(任务);
锁定。释放();
}
@凌驾
公开募捐{
同时(正在运行){
锁定。不间断地获取();
Task=queue.poll();
未来结果=执行者。提交(任务);
结果。添加(未来结果);
}
}
公共静态void main(字符串[]args){
DownloadTaskEnqueuer dte=新的DownloadTaskEnqueuer(10);
螺纹t=新螺纹(dte);
t、 start();
}
公共抽象类任务实现了可调用{
抽象对象下载();
抽象对象doProcess(对象下载对象);
@凌驾
公共对象调用()引发异常{
对象downloadeObject=download();
Object processingResult=doProcess(下载的对象);
返回处理结果;
}

}

执行者已经创建了线程池,并且已经知道如何正确地管理线程池及其任务队列,而不会出现死锁。当任务出现时,您应该向执行者提交任务。目前,您正在养一只狗,自己吠叫。
public class ProcessTask implements Runnable {
    private BlockingQueue<Task> processQueue;
    
    // constructor for initing queue
    
    @Override
    public void run() {
        while (true) {
           Task task = processQueue.poll();
           if (task != null) {
                task.getProcessTask().process();
           } else {
               // sleep 250 ms 
           }
        }
    }
}
createPool(10);

listener.listen((task) -> {
    downloadTaskEnqueuer.offer(task);
}
public class DownloadTaskEnqueuer implements Runnable {
private final BlockingQueue<Task>           queue       = new LinkedBlockingQueue<>();
private final LinkedList<Future<Object>>    results     = new LinkedList<>();
private final Semaphore                     lock        = new Semaphore(0);
boolean                                     isRunning   = true;
private final ExecutorService               executor;

public DownloadTaskEnqueuer(int parallismCount) {
    executor = Executors.newFixedThreadPool(parallismCount);
}

public void offer(Task task) {
    queue.offer(task);
    lock.release();
}

@Override
public void run() {
    while (isRunning) {
        lock.acquireUninterruptibly();
        Task task = queue.poll();
        Future<Object> futureResult = executor.submit(task);
        results.add(futureResult);
    }

}

public static void main(String[] args) {
    DownloadTaskEnqueuer dte = new DownloadTaskEnqueuer(10);
    Thread t = new Thread(dte);
    t.start();
}


public abstract class Task implements Callable<Object> {

abstract Object download();

abstract Object doProcess(Object downloadedObject);

@Override
public Object call() throws Exception {
    Object downloadedObject = download();
    Object processingResult = doProcess(downloadedObject);
    return processingResult;
}