我目前正在学习Java并发.我对代码行为的方式感到非常惊讶.
import java.util.concurrent.*;
public class Exercise {
static int counter = 0;
static synchronized int getAndIncrement() {
return counter++;
}
static class Improper implements Runnable {
@Override
public void run() {
for (int i = 0; i < 300; i++) {
getAndIncrement();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 300; i++) {
executorService.submit(new Improper());
}
executorService.shutdown();
System.out.println(counter);
}
}
Run Code Online (Sandbox Code Playgroud)
它不应该一直输出90000吗?相反,结果总是不同的.
什么是使主线程等到所有线程完成的最佳方法?
for(int i=0;i<n;i++){
Thread t=new Thread();
t.start();
}
//wait for all threads to finish
我有一个简单的java ExecutorService运行一些任务对象(实现Callable).
ExecutorService exec = Executors.newSingleThreadExecutor();
List<CallableTask> tasks = new ArrayList<>();
// ... create some tasks
for (CallableTask task : tasks) {
Future future = exec.submit(task);
result = (String) future.get(timeout, TimeUnit.SECONDS);
// TASKS load some classes and invoke their methods (they may create additional threads)
// ... catch interruptions and timeouts
}
exec.shutdownNow();
Run Code Online (Sandbox Code Playgroud)
在完成所有任务(DONE或TIMEOUT-ed)之后,我尝试关闭执行程序,但它不会停止:exec.isTerminated() = FALSE.
我怀疑某些被执行的任务未正确终止.
是的,我知道执行者的关闭不能保证任何事情:
除尽力尝试停止处理主动执行任务之外,没有任何保证.例如,典型的实现将通过{@link Thread#interrupt}取消,因此任何未能响应中断的任务都可能永远不会终止.
我的问题是,有没有办法确保这些(任务)线程终止?我提出的最佳解决方案是System.exit()在程序结束时调用,但这很简单.
我的程序完成后,我遇到一个问题就是结束线程.我运行一个线程时钟对象,它工作得很好,但我需要结束所有线程,当时间'=='一小时这一点似乎工作我只需要知道如何结束它们.下面是我所拥有的代码示例,除了此代码上面定义的一个int之外,这是run方法中唯一运行的东西.
@Override
public void run()
{
int mins = 5;
while(clock.getHour() != 1)
{
EnterCarPark();
if(clock.getMin() >= mins)
{
System.out.println("Time: " + clock.getTime() + " " + entryPoint.getRoadName() + ": " + spaces.availablePermits() + " Spaces");
mins += 5;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是当你继续观察在netbeans调试模式下运行的线程时,它们会在一小时后继续运行,但不确定如何解决这个问题.我尝试过中断调用,但似乎什么也没做.
我有一个ThreadPoolExecutor,当我调用getActiveCount()时,它似乎对我说谎.我没有做过很多多线程编程,所以也许我做错了.
这是我的TPE
@Override
public void afterPropertiesSet() throws Exception {
BlockingQueue<Runnable> workQueue;
int maxQueueLength = threadPoolConfiguration.getMaximumQueueLength();
if (maxQueueLength == 0) {
workQueue = new LinkedBlockingQueue<Runnable>();
} else {
workQueue = new LinkedBlockingQueue<Runnable>(maxQueueLength);
}
pool = new ThreadPoolExecutor(
threadPoolConfiguration.getCorePoolSize(),
threadPoolConfiguration.getMaximumPoolSize(),
threadPoolConfiguration.getKeepAliveTime(),
TimeUnit.valueOf(threadPoolConfiguration.getTimeUnit()),
workQueue,
// Default thread factory creates normal-priority,
// non-daemon threads.
Executors.defaultThreadFactory(),
// Run any rejected task directly in the calling thread.
// In this way no records will be lost due to rejection
// however, no records will be added …Run Code Online (Sandbox Code Playgroud) 在Java线程中,列表中可以有一些线程,将其启动,然后有一个主线程join,然后是另一个主线程,它要经过并等待所有进程完成后才能继续。
在其他模型中,我不确定您会怎么做。以RootTools 3.0 Command类为例。您创建一个Command有三个方法commandOutput,commandFinished,commandTerminated,虽然你可以使用一个回调在过程结束时做一些事情,我不知道你将如何等待多个进程(例如,经历几个目录列表并对文件大小求和)。
我相信Android Asynctask也会有类似的问题-您可以轻松进行回调,但是无法等待多个任务。除非我想念什么?
我正在学习如何使用Java在Java中使用线程池ExecutorService,这是我正在处理的示例:
public class Example {
static class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s) {
this.command = s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
processCommand();
System.out.println(Thread.currentThread().getName() + " End.");
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return this.command;
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(5); …Run Code Online (Sandbox Code Playgroud) 我有一个ThreadPoolExecutor- corePoolSize = 5,maxPoolSize = 10 queueSize = 10,keepAlive = 1000秒。我正在执行100 Runnable任务。实际执行的任务数量各不相同,并非全部执行。RejectionHandler也没有任何报告。我相信我对ThreadPoolExecutor的理解是错误的。有谁能够帮助我?如何执行所有任务?
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestThreadPoolExecutor {
public static void main(String[] args) {
ThreadFactory threadFactory = Executors.defaultThreadFactory();
ArrayBlockingQueue<Runnable> arrayBlockingQueue = new ArrayBlockingQueue<Runnable>(10);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10,1000, TimeUnit.SECONDS, arrayBlockingQueue, threadFactory, new RejectedExecutionHandlerImpl());
MonitorThread monitor = new MonitorThread(threadPoolExecutor, 3);
Thread monitorThread = new Thread(monitor);
monitorThread.start();
for (int i = 0; i < 100; i++) {
threadPoolExecutor.execute(new …Run Code Online (Sandbox Code Playgroud) 我在 Windows 11 x64、IntelliJ IDEA 2022 Ultimate 中使用 JDK/Java 19。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ZooInfo {
public static void main(String[] args) {
ExecutorService executorService = null;
Runnable runnable1 = () -> System.out.println("Printing zoo inventory");
Runnable runnable2 = () -> {
for (int i = 0; i < 3; i++) {
System.out.println("Printing record " + i);
}
};
try {
executorService = Executors.newSingleThreadExecutor();
System.out.println("Begin");
executorService.execute(runnable1);
executorService.execute(runnable2);
executorService.execute(runnable1);
System.out.println("End.");
} finally {
if (executorService != null) {
executorService.shutdown();
}
} …Run Code Online (Sandbox Code Playgroud)