- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
只是为了学习,我编写了以下用于自定义线程池的代码,引用并编辑显示的代码 here.
如代码所示,我使用 ArrayBlockingQueue 作为任务队列。
代码:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
public class ThreadPoolService {
private final BlockingQueue<Runnable> taskQueue;
private final int corePoolSize;
private ThreadPoolService(int corePoolSize) {
this.corePoolSize = corePoolSize;
this.taskQueue = new ArrayBlockingQueue<>(corePoolSize);
ThreadPool[] threadPool = new ThreadPool[corePoolSize];
for (int i = 0; i < corePoolSize; i++) {
threadPool[i] = new ThreadPool();
threadPool[i].start();
}
}
public static ThreadPoolService newFixedThreadPool(int size) {
return new ThreadPoolService(size);
}
public void execute(Runnable task) {
try {
taskQueue.offer(task, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class ThreadPool extends Thread {
Runnable task;
@Override
public void run() {
while (true) {
try {
while (!taskQueue.isEmpty()) {
task = taskQueue.remove();
task.run();
}
} catch (RuntimeException ex) {
ex.printStackTrace();
}
}
}
}
public static void main(String[] args) {
ThreadPoolService pool = ThreadPoolService.newFixedThreadPool(10);
Runnable task1 = () -> {
System.out.println(" Wait for sometime: -> " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable task2 = () -> System.out.println(" Do Task 2 -> " + Thread.currentThread().getName());
Runnable task3 = () -> System.out.println(" Do Task 3 -> " + Thread.currentThread().getName());
Runnable task4 = () -> System.out.println(" Do Task 4 -> " + Thread.currentThread().getName());
List<Runnable> taskList = new ArrayList<>();
taskList.add(task1);
taskList.add(task2);
taskList.add(task3);
taskList.add(task4);
for (Runnable task : taskList) {
pool.execute(task);
}
}
}
此代码有时运行良好,有时会出错。
成功输出:
Do Task 2 -> Thread-2
Wait for sometime: -> Thread-8
Do Task 3 -> Thread-6
Do Task 4 -> Thread-7
失败输出:
Do Task 4 -> Thread-3
Do Task 3 -> Thread-6
Wait for sometime: -> Thread-4
Do Task 2 -> Thread-7
java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at com.interview.java.ThreadPoolService$ThreadPool.run(ThreadPoolService.java:43)
java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at com.interview.java.ThreadPoolService$ThreadPool.run(ThreadPoolService.java:43)
java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at com.interview.java.ThreadPoolService$ThreadPool.run(ThreadPoolService.java:43)
我发现错误的原因是在队列为空时尝试删除元素。但它不应该,因为我正在第 42 行进行队列空检查(while (!taskQueue.isEmpty())
)。代码有什么问题以及为什么有时运行时没有错误?
最佳答案
在“while”检查和实际删除之间,队列可能会被另一个线程修改,可能会导致您提到的错误。这就是所谓的“竞争条件”。
因此,为了解决这个问题,您需要一种方法来阻止其他线程对队列的访问,可以通过“锁定”,或者使用带有共享锁对象的“同步” block 。或者简单地通过“轮询”而不是删除。
关于java - ArrayBlockingQueue NoSuchElementException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52463859/
当我阅读ArrayBlockingQueue.take方法的源代码时,我遇到了一个问题。 我认为两个线程同时调用 take 方法,只有一个线程可以成功获取锁,而另一个线程将在以下行等待锁:lock.l
我正在寻找与 ArrayBlockingQueue 类似的库。就是这样,我不需要它提供的线程安全功能(为了更好的性能目的),因为它在 offer(E e) 方法中使用了 ReentrantLock 。
我编写了解决有界生产者和消费者问题的程序。在构造 ArrayBlockingQueue 时,我定义了容量 100。我正在使用方法 take 和 put inside threads。而且我注意到有时我
我刚刚在研究 JDK 1.6 时发现ArrayBlockingQueue - 构造函数调用了公共(public)可重写方法之一!我认为这对于 API 来说是一种不好的做法。 public Array
ArrayBlockingQueue 中没有一个操作与它的任何其他操作并发;他们总是拿同一把锁。即使对于 size() 方法,它也需要一个锁。 public int size() {
我正在研究 BlockingQueue 接口(interface),其中 ArrayBlockingQueue 是一个实现。出于演示目的,我开发了以下代码: import java.util.conc
只是为了学习,我编写了以下用于自定义线程池的代码,引用并编辑显示的代码 here. 如代码所示,我使用 ArrayBlockingQueue 作为任务队列。 代码: import java.util.
场景:在我的消费者有机会消费之前,我的生产者填满了数组,比如 capacity new int[10]。我的生产者看到数组已满并阻塞。 然后我的消费者出现并删除了 int[0],并向生产者发出信号,该
关键字synchronize 没有出现在ArrayBlockingQueue 的源代码中。这是否意味着我可以出于“我自己的目的”自由使用它的内在锁?或者这会在未来发生变化吗? 最佳答案 一般来说,我会
我有两个线程,一个分派(dispatch)消息,另一个解析消息。简单,常见。我使用 ArrayBlockingQueue 进行同步,但不希望调度程序直接访问工作消息队列 - 我使用包装器。问题是是否应
您好,我很好奇是否有办法检查 ArrayBlockingQuery 查询当前是否被锁定?原因:我有一个服务器,它监听套接字,接收参数,处理它们,然后将一些结果返回给客户端。该服务器(假设是服务器 A)
我知道下面代码中进行的递增不是原子的。我希望增量、插入阻塞队列和打印计数器的值一起成为一个原子操作。我知道原子 int 但我正在尝试使用同步来使其工作以用于学习目的。 int counter = 0;
对于 Java 中的 ArrayBlockingQueue,queue.add(element) 是否会锁定它所在的线程?我有一个运行着数十个线程的应用程序,它们会将所有信息放入一个 ArrayBlo
我有一个 ArrayBlockingQueue,它有多个与数据库的连接。许多线程尝试通过轮询来获取连接。队列中可用的最大连接数为50,超过50后,线程必须等待连接放回才能获取数据库连接。 问题是我无法
我发现自己在重复这种模式,并且常常想知道这在 Java 中是否是惯用的,或者是否有更好的方法来实现这种行为。 问题:给定生产者/消费者设置,消费者想要处理批量的项目,因此它使用 drainTo(),但
我有一个简单的 ArrayBlockingQueue 测试如下: public class TestQueue { static class Producer implements Runna
ArrayBlockingQueue 包含一个作为数组的缓冲区。它还支持公认的低效 public boolean remove(Object o) Removal of interior elemen
我正在尝试编写一个像ArrayBlockingQueue这样的简单队列,其中如果在添加元素时队列已满,则队列的头部将被删除。该类应该只具有以下公共(public)方法 获取队列的大小 从队列头部获取一
这是我第一次在 StackOverflow 上提问。我遇到的问题如下: 我有一个生产者和消费者类。在 Producer 类中,我逐行读取文件并将这些文本行放入字符串列表中。当列表有 x 行时。该列表被
我正在尝试调整执行以下操作的线程: 只有 1 个线程的线程池 [CorePoolSize =0, maxPoolSize = 1] 使用的队列是 ArrayBlockingQueue 问题 = 20
我是一名优秀的程序员,十分优秀!