什么是ReentrantLock#tryLock(long,TimeUnit)实现在尝试获取锁时执行的操作?假设线程A实际上拥有Lock of myLock和Thread B调用myLock.tryLock(10,SECONDS),是线程B正在休眠还是在等待?
换句话说,这是两个实现的区别:
1.
while (true)
try {
if (readLock.tryLock())
return;
MILLISECONDS.sleep(5);
}catch (InterruptedException e) {}
Run Code Online (Sandbox Code Playgroud)
2.
while (true)
try {
if (readLock.tryLock(5,MILLISECONDS))
return;
}catch (InterruptedException e) {}
Run Code Online (Sandbox Code Playgroud) 据我所知,链表和数组都可以无限制地增长,或者我错了吗?但是当我查看Executor Service中的文档时,我看到了:
无限的队列.使用无界队列(例如,没有预定义容量的LinkedBlockingQueue)将导致新任务在所有corePoolSize线程忙时在队列中等待.因此,只会创建corePoolSize线程.(而且maximumPoolSize的值因此没有任何影响.)
Unbounded Queue当LinkedBlockingQueue具有已定义的容量时,属性是否会发生变化?
这写给ArrayBlockingQueue:
有界的队列.有限队列(例如,ArrayBlockingQueue)在与有限maximumPoolSizes一起使用时有助于防止资源耗尽,但可能更难以调整和控制.队列大小和最大池大小可以相互交换:使用大型队列和小型池最小化CPU使用率,OS资源和上下文切换开销,但可能导致人为的低吞吐量.如果任务经常阻塞(例如,如果它们是I/O绑定的),系统可能能够为您提供比您允许的更多线程的时间.使用小队列通常需要更大的池大小,这会使CPU更加繁忙,但可能会遇到不可接受的调度开销,这也会降低吞吐量.
在经历了痛苦的调试经历之后,我追踪了这个问题:ScheduledThreadPool不报告任务是否失败,并且不执行再次失败的任务.因此,很难跟踪周期性作业的活跃性,而不是用其他周期性任务(通过死人的开关或者ScheduledFuture)来检查它们.
现在我们可以提供ScheduledThreadPool一个UncaughtExceptionHandler,但即使这样做似乎也有效:
import java.util.concurrent.*;
class Test {
public static void main(String[] args) {
final ThreadFactory tf = new ThreadFactory() {
private final ThreadFactory delegate = Executors.defaultThreadFactory();
@Override public Thread newThread(final Runnable r) {
final Thread res = delegate.newThread(r);
res.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread t, final Throwable e) {
e.printStackTrace();
}
});
return res;
}
};
final ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1, tf);
final Runnable task = new Runnable() { …Run Code Online (Sandbox Code Playgroud) java error-handling concurrency scheduled-tasks java.util.concurrent
这个问题直接来自我在SO的上一个问题.我认为我的第二个问题的答案是否定的.所以我想理解为什么java.util.concurrent包中没有ConcurrentLinkedHashMap?我的意思是有一个ConcurrentHashMap但没有ConcurrentLinkedHashMap.在Concurrent环境中拥有这样的类是否完全没有意义?我的意思是它的非可用性的主要技术原因是什么?在Guava/Apache Commons中有类似的东西吗?
我希望懒洋洋地创建一些东西并将结果缓存为优化.下面的代码是安全有效的,还是有更好的方法来做到这一点?这里需要比较和设置循环吗?
...
AtomicReference<V> fCachedValue = new AtomicReference<>();
public V getLazy() {
V result = fCachedValue.get();
if (result == null) {
result = costlyIdempotentOperation();
fCachedValue.set(result);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
编辑:我的示例中设置的值来自expensiveIdempotentOperation(),无论什么线程调用它,它总是相同的.
我想执行CompletableFuture一次又一次的CompletableFuture完成,无论第一个是否异常完成(.thenCompose()仅在执行正常完成时运行).
例如:
CompletableFuture.supplyAsync(() -> 1L)
.whenComplete((v, e) -> CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000);
System.out.println("HERE");
} catch(InterruptedException exc) {
return;
}
}))
.whenComplete((v, e) -> System.out.println("ALL DONE"));
Run Code Online (Sandbox Code Playgroud)
这打印
ALL DONE
HERE
Run Code Online (Sandbox Code Playgroud)
我希望它是
HERE
ALL DONE
Run Code Online (Sandbox Code Playgroud)
优选地,不将第二个嵌套在第一个whenComplete()内部.
请注意,我不关心返回的结果/异常.
在JDK 1.6中,Doug Lea final在该next领域之前使用.
static final class HashEntry<K,V> {
final K key;
final int hash;
volatile V value;
final HashEntry<K,V> next;
Run Code Online (Sandbox Code Playgroud)
而在JDK 1.7中,next字段前面是volatile.我还注意到在JDK 1.7中,该get方法采用getObjectVolatile读取value字段的方法,该字段具有易失性加载语义.
我不知道Doug Lea之前使用过什么final.如果正确性存在问题,那么如何volatile在JDK 1.7(也是JDK 1.8)中替换它?
编辑:
具体来说,我的问题是我们可以final用volatileJDK 1.6的实现代替吗?
java concurrency hashmap concurrenthashmap java.util.concurrent
我想为工作窃取池使用的ForkJoinPool的线程设置名称,由.提供
ExecutorService newWorkStealingPool(int parallelism)
Run Code Online (Sandbox Code Playgroud)
要么
ExecutorService newWorkStealingPool()
Run Code Online (Sandbox Code Playgroud)
到目前为止,我找不到在这个线程上设置自定义名称ExecutorService的方法,有没有办法?
newWorkStealingPool()基本上提供了一个ForkJoinPool,但ForkJoinPool也没有提供名称模式的公共构造函数.
更新:我现在发现这个构造函数
ForkJoinPool需要一个线程工厂ForkJoinPool.ForkJoinWorkerThreadFactory.但是工厂应该返回a ForkJoinWorkerThread,它没有公共构造函数.所以我想我必须继承ForkJoinWorkerThread.
最近,我从" 多处理器编程的艺术 "第8章中读到了一些关于" 监视器和阻塞同步 "的例子,这些例子使用了signalAll()一个Condition对象,而没有获得与之相关的锁Condition.
令人惊讶的是,我没有在本书的勘误表中找到任何修复这些例子的方法.此外,他们建议对a的图8.12的例子进行修正FifoReadWriteLock,但他们继续使用signalAll()没有锁定的情况.这扰乱了我,我试图找到关于这些示例的其他注意事项,以了解这些Java示例以这种方式编写的原因.
例如,问题的答案 " 读写互斥锁如何工作?"显示了a的实现的相同示例FifoReadWriteLock,它实现了writeUnlock():
void writeUnlock() {
writer = false;
condition.signalAll();
}
Run Code Online (Sandbox Code Playgroud)
关于没有锁定获取,您可以阅读两个不同的原因:
由于本书使用了Java中的示例并明确说明了以下内容,因此很难接受第一个参数:
本书使用Java编程语言.
关于第二点,我知道方法的java.util.concurrent.locks.Condition状态中的Java API signal():
当调用此方法时,实现可能(并且通常确实)要求当前线程保持与此关联的锁
Condition.
如果仅" 实施可能 ",则意味着它不是强制性的.然而,据我所知,我发现任何不符合此要求的实施方案.所以我想知道哪些Java Condition实现不需要当前线程来保存锁?
parallel-processing multithreading locking java.util.concurrent concurrent-programming
Javadoc ConcurrentHashMap#computeIfAbsent说
计算应该简短,并且不得尝试更新此映射的任何其他映射.
但是,从我看到的,使用remove()和clear()内部方法mappingFunction工作正常.例如这个
Key element = elements.computeIfAbsent(key, e -> {
if (usages.size() == maxSize) {
elements.remove(oldest);
}
return loader.load(key);
});
Run Code Online (Sandbox Code Playgroud)
在内部使用remove()方法有什么不好的后果mappingFunction?