在这些节目中我应该选择哪一个?为什么?一般来说问题是为什么我应该选择使用PriorityBlockingQueue优先于PriorityQueue.
的PriorityBlockingQueue
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueExample {
static PriorityBlockingQueue<String> priorityQueue = new PriorityBlockingQueue<String>();
public static void main(String[] args) {
new Thread(){
public void run(){
try {
System.out.println(priorityQueue.take() +" is removed from priorityQueue object");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
new Thread(){
public void run(){
priorityQueue.add("string variable");
System.out.println("Added an element to the queue");
}
}.start();
}
}
Run Code Online (Sandbox Code Playgroud)
在这些节目中我应该选择哪一个?为什么?一般来说问题是为什么我应该选择使用PriorityBlockingQueue优先于PriorityQueue.的PriorityQueue
import java.util.PriorityQueue;
public class PriorityQueueTest {
static PriorityQueue<String> priorityQueue = new PriorityQueue<String>();
private static …Run Code Online (Sandbox Code Playgroud) 如果 corePoolSize 或更多线程正在运行,Executor 总是更喜欢对请求进行排队而不是添加新线程。
如果运行的线程数大于 corePoolSize 但小于 maxPoolSize,则仅当队列已满时才会创建新线程。
有没有办法让执行器更喜欢创建新线程,直到达到最大值,即使有超过核心大小的线程,然后开始排队?如果队列达到最大大小,任务将被拒绝。如果在处理繁忙突发后,超时设置能够启动并删除线程至核心大小,那就太好了。我明白了为什么更喜欢排队以便进行限制;然而,这种定制还允许队列主要充当尚未运行的任务列表。
我在Spring中使用ThreadPoolTaskExecutor来安排我的任务.
有没有办法获得该任务执行器/池的每个运行和排队线程的列表或内容?
我有一个递归的分治算法,在开始分割之前需要两个计算密集的基本案例任务.最初的基本案例是独立的任务,所以我想并行完成.在基本情况之后,除法运行相同的任务,在0和1之间输入不同的输入,并根据输出决定是否再次拆分.我通过创建一个伪造递归的任务包装器对象来使基本案例工作,但这感觉就像一个kludge,如下所示:
public static void doSomething () {
ForkJoinPool pool = new ForkJoinPool();
private ArrayList<Object> al = new ArrayList<Object>();
TaskWrapper tw = new TaskWrapper(true,-1);
al.addAll(pool.invoke(tw));
}
@SuppressWarnings("serial")
public static class TaskWrapper extends RecursiveTask<ArrayList<Object>> {
private ArrayList<Object> al = new ArrayList<Object>();
private boolean arg;
private double input;
private Object out;
TaskWrapper(boolean ar, double in){
arg = ar;
input = in;
}
@Override
public ArrayList<Object> compute() {
if (arg == false) {
out = new Object(runIntensiveTask(input));
al.add(out);
}
else {
// Right Base …Run Code Online (Sandbox Code Playgroud) java multithreading java.util.concurrent fork-join forkjoinpool
鉴于队列的以下变化:
interface AsyncQueue<T> {
//add new element to the queue
void add(T elem);
//request single element from the queue via callback
//callback will be called once for single polled element when it is available
//so, to request multiple elements, poll() must be called multiple times with (possibly) different callbacks
void poll(Consumer<T> callback);
}
Run Code Online (Sandbox Code Playgroud)
我发现我不知道如何使用 java.util.concurrent 原语来实现它!所以问题是:
我将任务安排为:
ScheduledExecutorService dataService = Executors.newScheduledThreadPool(1);
Future<?> dataTimerHandle = dataService.scheduleAtFixedRate(runnable, 100, freq, TimeUnit.MILLISECONDS);
Run Code Online (Sandbox Code Playgroud)
这工作正常,没有缺陷。
但是,当某个标志变为true用户操作时,便不再需要定期执行任务,而只需执行一次即可。然后,我尝试取消任务并仅提交一次,如下所示:
if(!dynamicUpdate) {
dataTimerHandle.cancel(true);
dataTimerHandle = dataService.submit(runnable);
}
else { //Reschedule again:
dataTimerHandle = dataService.scheduleAtFixedRate(runnable, 100, freq, TimeUnit.MILLISECONDS);
}
Run Code Online (Sandbox Code Playgroud)
但是似乎可运行对象仍在定期执行并且cancel()未按预期工作。是否有其他替代策略?
java concurrency multithreading executorservice java.util.concurrent
我已经在https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html上阅读了有关该问题的信息。
这是文档对这两个条件的说明:
我们希望继续等待 put 线程并将线程放在单独的等待集中,以便我们可以使用优化,当缓冲区中的项目或空间可用时,一次只通知单个线程。这可以使用两个 Condition 实例来实现。
因为signal()唤醒了一个线程,所以我可以使用一个条件通知单个线程:
class BoundedBuffer2 {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
condition.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
condition.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count …Run Code Online (Sandbox Code Playgroud) java multithreading synchronization producer-consumer java.util.concurrent
Java内存模型是否为Thread Pool交互提供了先前发生的保证?特别是,在工作队列中运行项目结束之前由线程池工作线程进行的写入是否会在之后从队列中运行下一个项目的工作线程可见?
规范(我个人觉得这个常见问题解答很有用:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization)声明"对a的调用start()线程在启动线程中的任何操作之前发生. "或者简单地说,在启动线程之前所做的任何内存写入都将在执行之前执行并且对run()方法可见.对于线程池,它是不同的,start()通常在您进行写入之前运行.考虑一个简单的工作流,其中上下文对象被变异并传递给下一个动作:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
private static class Container<T> {
private T value;
public T get() {
return value;
}
public void set(T newValue) {
value = newValue;
}
}
public static void main(String[] args) {
final Container<Integer> sharedObject = new Container<>();
final ExecutorService executor = Executors.newFixedThreadPool(10);
// SKIPPED: pre-warm the executor so all worker threads are start()'ed
final Runnable read = () -> System.out.println("Got " + …Run Code Online (Sandbox Code Playgroud) 我想要并发的一组字符串值,按长度最长->最短排序。
这是我的代码(JAVA 8):
private ConcurrentSkipListSet<String> sortedSourceTypeNames = new ConcurrentSkipListSet<>(Comparator.comparing(String::length).reversed());
Run Code Online (Sandbox Code Playgroud)
这是Java 8文档:
/**
* Constructs a new, empty set that orders its elements according to
* the specified comparator.
*
* @param comparator the comparator that will be used to order this set.
* If {@code null}, the {@linkplain Comparable natural
* ordering} of the elements will be used.
*/
public ConcurrentSkipListSet(Comparator<? super E> comparator) {
m = new ConcurrentSkipListMap<E,Object>(comparator);
}
Run Code Online (Sandbox Code Playgroud)
现在这是奇怪的事情:
调试此现象后,我看到ConcurrentSkipListSet拒绝了新的唯一字符串,这些字符串的长度与集合中现有字符串的长度相同。
我就像瓦阿特(Waaaattt)?!?!? …
这里:
当对象的构造函数完成时,该对象被认为已完全初始化。仅在对象完全初始化后才能看到对该对象的引用的线程保证看到该对象的最终字段的正确初始化值。
现场是否有同样的保证volatile?如果y下面的例子中的字段是volatile我们可以观察到的呢0?
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
Run Code Online (Sandbox Code Playgroud)
}