当使用下面的代码创建线程池时,Executor如何选择合适的值nThreads?我可以向 android 询问设备拥有的核心数量,然后使用该信息来计算这个数字吗?在这种情况下这个数字应该是多少?
Executor executor = Executors.newFixedThreadPool(nThreads);
Run Code Online (Sandbox Code Playgroud) 我有一个类,它实现了Runnable接口,并且是一个一旦启动就会无限期运行的任务(一个长时间运行的线程)。
public class LongRunningTask implements Runnable {
@Override
public void run() {
//stuff happening here
}
}
Run Code Online (Sandbox Code Playgroud)
一个简单的ExecutorService/ThreadPoolExecutor创作:
final ExecutorService executorService = Executors.newFixedThreadPool(8);
Run Code Online (Sandbox Code Playgroud)
如果LongRunningTask实际启动/执行,我能够观察到它的实际结果,因此,我注意到了这一点:
如果我传递给它执行executorService.execute(() -> new LongRunningTask());,它根本不会执行,也不会有结果。
如果我通过它来执行executorService.execute(new LongRunningTask());它,它将按照它应该的方式执行并且会有结果。
使用 的 lambda 语法有() ->什么区别?
首先我创建了一个空文件,然后我调用了一些线程来搜索数据库并获取结果内容,然后附加到文件中。结果内容为Stringtype,可能为20M。每个线程应该一次写入一个文件。我测试了很多次,我发现没有必要锁定。那正确吗?例子总共1000行,什么时候需要加写锁对文件进行操作?
String currentName = "test.txt";
final String LINE_SEPARATOR = System.getProperty("line.separator");
ThreadPoolExecutor pool = new ThreadPoolExecutor(
10, 100, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
for (int i = 0; i < 500; i++) {
pool.execute(() -> {
try {
appendFileByFilesWrite(currentName, "abc" +
ThreadLocalRandom.current().nextInt(1000) + LINE_SEPARATOR);
} catch (IOException e) {
e.printStackTrace();
}
});
}
IntStream.range(0, 500).<Runnable>mapToObj(a -> () -> {
try {
appendFileByFilesWrite( currentName,
"def" + ThreadLocalRandom.current().nextInt(1000) +
LINE_SEPARATOR);
} catch (IOException e) {
e.printStackTrace();
}
}).forEach(pool::execute);
pool.shutdown();
Run Code Online (Sandbox Code Playgroud)
这是方法:
public static …Run Code Online (Sandbox Code Playgroud) java multithreading java.util.concurrent java-8 threadpoolexecutor
我想知道是否在 ConcurrentHashMap 的 putIfAbsent 方法中实际执行了 'put' 操作。
这就是我要的:
if(map.putIfAbsent(Key,Value)){//Clearly this is wrong
return true;
}
//other operation
return false;
Run Code Online (Sandbox Code Playgroud) 在多线程环境中,我正在 ConcurrentHashMap 实现上执行 get 和 put 操作。然而,结果却出乎意料。请找到下面的代码和输出。
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
private static final List<String> bars = Arrays.asList("1","2","3","4","5","6","7","8","9","10");
private static final String KEY = UUID.randomUUID().toString();
private static ExecutorService executorService = null;
public static void main(String[] args) {
for (int i = 1; i <= 20; i++) {
executorService = Executors.newFixedThreadPool(2);
Map<String, AtomicInteger> map = new ConcurrentHashMap<>();
performMapOps(map);
executorService.shutdown();
try {
while (!executorService.awaitTermination(1, …Run Code Online (Sandbox Code Playgroud) 请考虑以下来自java.util.concurrent.locks.AbstractQueuedSynchronizer的代码,作为标题中提出的想法的众多示例之一:
1258 public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws Interrupted Exception {
1259 if (Thread.interrupted())
1260 throw new InterruptedException();
1261 return tryAcquireShared(arg) >= 0 ||
1262 doAcquireSharedNanos(arg, nanosTimeout);
1263 }
Run Code Online (Sandbox Code Playgroud)
为什么大多数阻塞库方法通过调用静态方法Thread.interrupted()而不是实例方法来响应中断isInterrupted().调用静态方法也会清除中断状态,因此即使任务处理代码吞下InterruptionException,调用者也无法知道除了中断状态之外的其他状态.
我是高级Java.util.Concurrent包的新手,我想要做的是使用线程池同时读取多个文本文件.我需要一种方法将文件名作为参数传递给我的调用方法实现.
像这样的东西:
public String call (String param)
Run Code Online (Sandbox Code Playgroud)
如果还有其他方法可以实现这一点,我将非常感谢您的帮助.
ConcurrentHashMap支持atomic getOrDefault(Object key, V defaultValue),其中
返回指定键映射到的值,如果此映射不包含键的映射,则返回给定的默认值.
我的问题是:
如何
ConcurrentHashMap通过提供原子操作来增强,比方说getOrDefaultWithPut(Object key, V defaultValue),哪个"返回指定键映射,或第一次价值放在了给定的默认值到地图中,然后返回默认值,如果此映射包含的key.`没有映射"
我的解决方案
目前我有一Wrapper类
private ConcurrentMap<K, V> map = new ConcurrentHashMap<>();
Run Code Online (Sandbox Code Playgroud)
方法是:
public synchronized K getOrDefaultWithPut(K key, V defaultValue)
{
map.putIfAbsent(key, defaultValue);
return map.get(key);
}
Run Code Online (Sandbox Code Playgroud)
- 这个实现是否是线程安全的?
- 有
synchronized必要吗?如果它被删除会发生什么不好?- 如果
getOrDefaultWithPut(K key, V defaultValue)是唯一的公共方法Wrapper,这个实现是线程安全的并且是synchronized必要的吗?
java collections synchronized concurrenthashmap java.util.concurrent
我的电脑有8个内核和64G内存.我的使用多线程的方式如下吗?它处理来自每个文档的一行(filePath)并将结果存储到Document列表中,最后返回.
问题是,当设置'4'线程时,我没有看到它运行得更快.花在测试数据上的时间总是与单线程运行所需的时间相同.我使用Callable的方式有什么问题吗?
List<Document> processDocs(String filePath) {
ExecutorService pool = Executors.newFixedThreadPool(4);
List<Document> processedDocs = new ArrayList<>();
try {
br = new BufferedReader(IOUtils.fileReader(filePath));
String line = null;
int docNo=0;
while ((line = br.readLine()) != null) {
line = line.trim();
Callable<Document> callable = new NLPTextThread(line, ++docNo);
Future<Document> future = pool.submit(callable);
try {
processedDocs.add(future.get());
} catch (InterruptedException e) {
log.error("InterruptedException " + line);
} catch (ExecutionException e) {
log.error("ExecutionException: " + line);
e.printStackTrace();
}
}
pool.shutdown();
return processedDocs;
}
Run Code Online (Sandbox Code Playgroud)
编辑:关于'docNo'变量的线程安全性的另一个问题.我想将doc序列号传递给Callable.在这种情况下,"docNo"变量的线程安全吗?
问题出在哪儿?ReentrantLock未显示预期结果.两个线程正在执行相同的时间而不是等待一个线程.
class MyThread2 extends Thread{
String name;
ReentrantLock reentrantLock = new ReentrantLock();
MyThread2(String name){
this.name = name;
}
public void run(){
do {
try {
if (reentrantLock.tryLock(20,TimeUnit.MILLISECONDS)){
System.out.println("executing : "+ name);
Thread.sleep(500);
reentrantLock.unlock();
break;
}else {
System.out.println("waiting "+ name);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}while (true);
}
}
public class LockDemo2{
public static void main(String[] args) {
new MyThread2("Thread - 1").start();
new MyThread2("Thread - 2").start();
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
executing : Thread - 1
executing : …Run Code Online (Sandbox Code Playgroud) java concurrency multithreading java.util.concurrent reentrantlock