有人可以解释每个连接的每个请求和线程的线程是什么?servlet工作的模型是什么?如何分配线程来处理HTTP请求?是线程/请求还是连接?
让我们说如果我想在我Servlet
的doGet()
方法中异步执行一个耗时的任务,我会使用Java执行程序启动一个新线程,以便在一个单独的线程中完成冗长的计算,并立即发送响应.
现在这样做是否确保我已经释放了处理我的线程,HttpServletRequest
或者它仍然被使用,因为子线程仍在运行?
如何使用C++中的boost创建线程池,如何将任务分配给线程池?
我正在使用spring boot app开发应用程序服务器,但现在我想知道spring中默认的最大(客户端请求)线程池大小是什么,我该如何自定义该值?
我一直在阅读线程池模式,我似乎无法找到以下问题的通常解决方案.
我有时希望连续执行任务.例如,我从文件中读取文本块,由于某种原因,我需要按顺序处理块.所以基本上我想消除一些任务的并发性.
考虑这种情况,其中*
需要按照推入的顺序处理任务.其他任务可以按任何顺序处理.
push task1
push task2
push task3 *
push task4 *
push task5
push task6 *
....
and so on
Run Code Online (Sandbox Code Playgroud)
在线程池的上下文中,没有这个约束,一个待处理任务的单个队列工作正常,但在这里它没有.
我想过让一些线程在特定于线程的队列上运行,而其他线程在"全局"队列上运行.然后,为了以串行方式执行某些任务,我只需将它们推送到单个线程所在的队列中.这确实听起来有点笨拙.
所以,这个长篇故事中的真正问题是:你将如何解决这个问题?您如何确保订购这些任务?
作为一个更普遍的问题,假设上面的场景变为
push task1
push task2 **
push task3 *
push task4 *
push task5
push task6 *
push task7 **
push task8 *
push task9
....
and so on
Run Code Online (Sandbox Code Playgroud)
我的意思是组内的任务应该按顺序执行,但组本身可以混合使用.所以你可以3-2-5-4-7
举个例子.
另外需要注意的是,我无法预先访问组中的所有任务(我不能等到所有任务在启动组之前到达).
感谢您的时间.
注意:它的错误是在WaitHandle.WaitAll(doneEvents)行; 我正在使用标准的WPF项目.
private void Search()
{
const int CPUs = 2;
var doneEvents = new ManualResetEvent[CPUs];
// Configure and launch threads using ThreadPool:
for (int i = 0; i < CPUs; i++)
{
doneEvents[i] = new ManualResetEvent(false);
var f = new Indexer(Paths[i], doneEvents[i]);
ThreadPool.QueueUserWorkItem(f.WaitCallBack, i);
}
// Wait for all threads in pool
WaitHandle.WaitAll(doneEvents);
Debug.WriteLine("Search completed!");
}
Run Code Online (Sandbox Code Playgroud)
更新:以下解决方案不适用于WPF应用程序!无法将主应用程序属性更改为MTAThreadAttribute.这将导致以下错误:
错误: "不支持在STA线程上使用多个句柄的WaitAll."
我有以下代码抛出异常:
ThreadPool.QueueUserWorkItem(state => action());
Run Code Online (Sandbox Code Playgroud)
当操作抛出异常时,我的程序崩溃了.处理这种情况的最佳做法是什么?
在Spring Web应用程序中,我有几个DAO和服务层bean.一个服务层bean具有带注释的@Async/@Scheduled方法.这些方法依赖于其他(自动装配的)bean.我在XML中配置了两个线程池:
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="2" />
<property name="maxPoolSize" value="5" />
<property name="queueCapacity" value="5" />
<property name="waitForTasksToCompleteOnShutdown" value="true" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
</property>
</bean>
<bean id="taskScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="poolSize" value="10" />
<property name="waitForTasksToCompleteOnShutdown" value="true" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
</property>
</bean>
<task:annotation-driven executor="taskExecutor" scheduler="taskScheduler"/>
Run Code Online (Sandbox Code Playgroud)
一切都按预期工作.我的问题是我无法完全关闭任务池.任务在数据库和文件系统上运行.当我停止Web应用程序时,它需要一些时间才能停止.这表明该waitForTasksToCompleteOnShutdown
物业有效.但是,我在日志中得到IllegalStateExceptions,表明某些bean已经被销毁但是一些工作任务线程仍在执行,并且它们因为依赖项被破坏而失败.
有一个JIRA问题可能是相关的:SPR-5387
我的问题是:有没有办法告诉Spring最后初始化任务执行程序/调度程序bean还是有办法告诉Spring先破坏它们吗?
我的理解是,销毁是以颠倒的初始顺序进行的.因此,最后初始化的bean将首先被销毁.如果首先销毁线程池bean,则所有当前正在执行的任务都将完成,并且仍然可以访问依赖bean.
我还尝试在引用我的服务bean的线程池上使用depends-on属性,该服务bean具有@Async和@Scheduled注释.好像它们从未执行过,我没有得到上下文初始化错误.我假设带注释的服务bean在某种程度上需要首先初始化这些线程池,如果我使用依赖,我会颠倒顺序并使它们不起作用.
什么是C++在生产代码中使用的线程池的良好开源实现(类似于boost)?
请提供您自己的示例代码或示例代码使用的链接.
在我的Java类中,我有时会ThreadLocal
主要使用一种方法来避免不必要的对象创建:
@net.jcip.annotations.ThreadSafe
public class DateSensitiveThing {
private final Date then;
public DateSensitiveThing(Date then) {
this.then = then;
}
private static final ThreadLocal<Calendar> threadCal = new ThreadLocal<Calendar>() {
@Override
protected Calendar initialValue() {
return new GregorianCalendar();
}
};
public Date doCalc(int n) {
Calendar c = threadCal.get();
c.setTime(this.then):
// use n to mutate c
return c.getTime();
}
}
Run Code Online (Sandbox Code Playgroud)
我这样做是出于正当的原因 - GregorianCalendar
是那些光荣的有状态,可变,非线程安全的对象之一,它提供跨多个调用的服务,而不是表示值.此外,它被认为是"昂贵的"实例化(这是否真实不是这个问题的重点).(总的来说,我真的很佩服它:-))
但是,如果我在任何聚集线程的环境中使用这样的类 - 并且我的应用程序无法控制这些线程的生命周期 - 那么就有可能发生内存泄漏.Servlet环境就是一个很好的例子.
事实上,当一个webapp停止时,Tomcat 7就像这样嘶嘶作响:
严重:Web应用程序[]创建了一个ThreadLocal,其键为[org.apache.xmlbeans.impl.store.CharUtil $ 1](值[org.apache.xmlbeans.impl.store.CharUtil$1@2aace7a7])和一个值类型为[java.lang.ref.SoftReference](值[java.lang.ref.SoftReference@3d9c9ad4]),但在Web应用程序停止时无法将其删除.线程将随着时间的推移而更新,以避免可能的内存泄漏.2012年12月13日下午12:54:30 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
(在特定情况下,甚至我的代码都没有这样做).
我的多线程概念很薄弱并且正在努力学习.
在我所知道的java中,我们不能再调用一次线程即ie
Thread t = new Thread; //Some Runnable
t.start();
t.start(); //Illegal and throw Exception at runtime.
Run Code Online (Sandbox Code Playgroud)
据我所知,当你再次调用t.start()时会抛出异常,因为一旦它离开t.start()
方法并且你试图再次初始化东西,Thread的相关堆栈就会被销毁.
在这种情况下,我对Threadpool的了解是,它提供了更好的性能并节省了时间,因为不需要创建新线程.(我在http://www.javatpoint.com/thread-pooling-in-java上读到)
如果不需要在ThreadPool场景中创建新的Thread,那么它如何与刚刚完成其run方法的同一个线程一起工作,那么Thread是否可以再次使用?
我读了这篇http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html ,它说" java.util.concurrent中的大多数执行器实现使用线程池,它由工作线程组成这种线程与它执行的Runnable和Callable任务分开存在,通常用于执行多个任务. "
那么这里的Worker线程是什么,它与普通的Java Threads有什么不同?
使用此链接缓存线程池如何重用现有线程我得到了一些东西但仍然混淆了当我们使用线程池时可以消除哪种东西,并且使用普通Java线程提供更好的性能.
我们可以这样说,
线程有三个部分,
因此,考虑到上述3个步骤,使用Threadpool步骤1和步骤3可以在固定数量的线程创建后消除.只执行每个任务的第2步,这就是为什么Threadpool更快?我们可以这样说吗?我对么?
threadpool ×10
java ×4
concurrency ×3
boost ×2
boost-thread ×2
c# ×2
c++ ×2
.net ×1
boost-asio ×1
java-ee ×1
servlets ×1
spring ×1
spring-boot ×1
thread-local ×1