【发布时间】:2019-03-11 03:03:41
【问题描述】:
Java concurrent API 提供了许多有用的库和功能,可以更轻松地处理异步和多线程控制流。其中一项功能是Thread Pools。
今天早些时候,我正在试验并发 API,并注意到一些关于从线程池中选择线程的奇怪模式。他们让我想知道线程选择背后的逻辑是什么。下面是一些示例代码,也许可以为您提供我正在谈论的示例。当程序记录每个tick 时,您会注意到线程名称中的模式(在[ ] 内)。虽然,该模式可能不会出现在 64 位 Windows 10 机器上的 Oracle JDK 1.8.0_161 以外的 JDK 版本上。
无论如何,我的问题与任何巧合的模式关系不大,而是关于从线程池中选择线程的过程。这个模式让我相信它不是完全随机的,那么这个选择背后的逻辑是什么?谢谢。 :)
public static void main(String[] args)
{
// create a ScheduledExecutorService with a Thread Pool of 7 threads
ScheduledExecutorService ses = Executors.newScheduledThreadPool(7);
log("go");
// starts a timer of 30 seconds, shutting down ses afterwards
ses.schedule(() -> call(ses), 30, TimeUnit.SECONDS);
// starts the ticker
ses.schedule(() -> tick(ses, 1), 1, TimeUnit.SECONDS);
}
// ticks once per second, logging the current tick counter. (i.e, counts
// by 1 each second) ticking ends when ses is shutdown.
public static void tick(ScheduledExecutorService ses, int count)
{
if (!ses.isShutdown())
{
log("tick %d", count);
ses.schedule(() -> tick(ses, count + 1), 1, TimeUnit.SECONDS);
}
}
// called when it's time to shutdown ses.
public static void call(ScheduledExecutorService ses)
{
log("done");
ses.shutdown();
}
// formats and logs the given message alongside a timestamp and the name
// of the executing thread
public static void log(String s, Object...args)
{
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
String time = sdf.format(new Date(System.currentTimeMillis()));
String thread = Thread.currentThread().getName();
String message = String.format(s, args);
String log = String.format("%s [%s] - %s", time, thread, message);
System.out.println(log);
}
【问题讨论】:
-
你实际上已经创建了一个远非“真正随机”的 ScheduledThreadPool docs.oracle.com/javase/8/docs/api/java/util/concurrent/…
-
属于同一个线程池的工作线程是完全可以互换的。为什么你想知道任何给定工作线程的身份?
-
@besmirched 没有理由,只是好奇。
-
您是否尝试过查看 OpenJDK 源代码? hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/…
标签: java multithreading concurrency threadpool java.util.concurrent