我试图了解有关newSingleThreadExecutor
的一些信息-下面如何说,当没有提到ThreadFactory
时,它会按顺序执行任务。
public static ExecutorService newSingleThreadExecutor()
创建一个执行程序,该执行程序使用在无限队列中运行的单个工作线程。(但请注意,如果此单个线程由于在关闭前执行期间失败而终止,则如果需要执行后续任务,将有一个新的线程代替它。保证任务按顺序执行,并且在任何给定时间不超过一个任务处于活动状态。与其他等效的newFixedThreadPool(1)
不同,返回的执行器保证不能重新配置为使用其他线程。
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory)
创建一个执行程序,该执行程序使用在无限队列中操作的单个工作线程,并在需要时使用提供的 ThreadFactory 创建新线程。与其他等效newFixedThreadPool(1, threadFactory)
不同,返回的执行器保证不能重新配置为使用其他线程。
参数:
但是给定下面的示例,我正在使用线程工厂:
executor = Executors.newSingleThreadExecutor(getPrioritisedFactory());
`private ThreadFactory getPrioritisedFactory() {
ThreadFactory prioritisedFactory = new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(r, recSocketServerThreadID);
t.setPriority(Thread.MAX_PRIORITY);
return t;
}
};
return prioritisedFactory;
}`
似乎不再尊重顺序了。是因为线程具有相同的优先级,然后开始随机选择它们吗?从Java帮助中不太清楚何时使用工厂时发生。
谢谢。
谢谢我到现在为止得到的答案。下面是更多代码和解释。 我在高负载条件(1000 个提交的线程)的日志中发现一个线程 首先提交的是
后来提交的其他一些提交。该示例已简化,但 MyThread.run 方法中没有更多代码可以延迟日志记录。
- 1:00:01.100 DEB 新线程[id:500]
- 1:02:01.160 DEB 新线程[id:900]
- 1:03:01.200 战争 已启动线程 [thID:900]
- 1:04:02.200 战争 已启动线程 [thID:500]
private ExecutorService executor;
executor = Executors.newSingleThreadExecutor(getPrioritisedFactory());
....
//Keep adding threads here
MyThread mine=MyThread();
System.out.println(String.format("new thread[id:%d]",
mine.getId()));
executor.execute(mine);
public class MyThread extends Thread
{
@Override
public void run() {
long startTimeMillis = System.currentTimeMillis();
long currentTimeMillis = System.currentTimeMillis();
long delayMillis = currentTimeMillis - this.createTimeMillis;
logger.warn(String.format("Started thread [thID:%d]",
this.getId()));
........
}
}
每个Executor
都使用ThreadFactory
来创建所需的线程。如果您没有明确提供一个,它将采用一个默认的线程,该线程返回一个相当普通的线程,但带有名称。
没有工厂的方法只会委托给有的方法。
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
执行器开始时根本没有线程,他们会在需要时创建一个线程。他们可以同时使用的线程数量取决于它们的配置。
如果一个线程由于某种原因死亡,他们可以创建一个新线程来替换它。SingleThreadExecutor
保证永远不会使用超过 1。
可以保证代码按顺序执行,但不保证代码始终是同一线程。
Executors.newSingleThreadExecutor() 实际上为您提供了一个 ExecutorService 实例,它保证它一次只使用一个线程来执行您提交的任务。您提交的任务将按顺序执行。
摘自遗嘱执行人.java来源,
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
要ThreadPoolExecutor
的第二个参数是最大线程池大小。newSingleThreadExecutor
对此参数使用 1,这保证您一次最多使用一个线程。