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