在java web当中,servlet在运行阶段,针对每个客户端的请求,都会创建一个线程,该线程调用servlet的实例?
谢邀。
处理http请求的线程由JAVA WEB Server来管理。比如tomcat,jetty等。通常的作法是维护一个线程池,所有请求的执行都由这个线程池中的线程来完成,如果请求超过处理能力,就会发生等待甚至崩溃的情况,因此根据业务的访问量合理的设置线程池大小是非常重要的。
以tomcat为例,下面的源代码是tomcat处理http请求初始化的代码。可以从源代码中看出,tomcat会初始化一个ThreadPoolExecutor实例,而其中的参数可以在tomcat配置文件中进行配置。
希望可以解答题主的疑问。
不是的。不是创建,创建通常指给程序分配空间,在Java中所谓创建线程是指创建线程实例。而Web容器中负责请求处理的Servlt只是初次或实例实在不够分配给引用的时候才创建实例(线程对象),否则通常情况下就直接启动个线程(针对每个请求)来接受并分发请求(调用实例)。另外,一般没有人会用它保管用户的状态,所以它的实例与访问量(请求对象个数)绝不对称。对称的是线程,且分发掉请求就立刻熄灭。实例如同太阳,线程如同太阳的光线(不占地方)。另外,像地球这么大儿的地儿,一般一个太阳就够了。一个站点慢或卡跟它没关系。
不是每个调用都有新线程产生,这样的话,并发量一上来不出几分钟就要挂了。主流的容器都有线程池,也就是最多同时可以接受多少连接,超过这个数的连接都要等待可用的线程才能处理。所以,在有空闲线程时不会创建新线程,就算没空闲线程也得满足条时才创建。
应该不是这样的原理
线程虽然异步,可以提升cpu的运行速率,但是线程过多也会造成cpu负荷过重,比如上下文切换,比如保存线程的堆栈信息等
而一般一个网站同时访问量会达到几百万到上千万,如果线程到达这个级别,服务器会卡死
java多线程如何实现在多CPU上分布?
一个JAVA线程就是一个OS线程,线程调度依赖于操作系统,JVM层面不干预。
JAVA语言层面讲,只是规范,并不要求具体如何实现。具体的实现模型有几种,比如1:1,N:1, 1:N,具体怎么选,JVM厂商自己的事儿。
在LINUX下,你可以用JNI来调用taskset,实现把线程分配到某一个CPU上。但是这么做的理由我现在还想不出来。
Java内存模型的核心问题就是如何解决一致性问题?
java内存模型其实是跟计算机硬件发展息息相关的,CPU的运算能力相比较于硬盘,内存的存取能力是相当高的,就好比我(CPU)分明能一分钟从1加到100,你(内存)却只能给到我1到10,内存的存取大大的限制了CPU的运算,所以就在内存和CPU中间加了高速缓存,用于CPU的快速计算,如下图:
JAVA内存模型也采用了相似的结构,线程与CPU交互的时候,为了快速的进行运算,线程本地会开辟一份内存用于数据存储,然后快速的与CPU进行交互,CPU的运算数据也通过线程推送到内存中,如下图:
现在问题来了,从CPU到主内存需要经过线程的本地内存,在多线程的环境下,如果CPU运算数据不能及时的推到主内存中,就引发了线程安全问题,比如java中的经典案例i=0;i++;这么一个简单地语句,如果线程1将i变为1之后还没来得及写到主内存中,线程2也是用i=0这个数据去运算,那么原本i++两次之后应该得到2,现在却只能输出1;
由此可见java内存模型是模拟计算机硬件设计的,主要的作用其实还是用来提升整个系统的运算能力,但却由此产生了多线程的线程安全问题,线程安全的主要问题是原子性,可见性,有序性问题;
怎么解决线程安全的问题呢?
1,资源不共享:比如TheadLocal,数据直接放在线程的本地内存中,每个线程有一份自己的数据,不存在安全问题
2,资源共享但是加锁:比如synchronize,reentrantLock等,将共享资源进行加锁,只有在保证线程处理完成或者中断的时候,才会让别的线程继续处理这份数据;
3,资源共享但是无锁:比如AtomicBoolean,AtomicInteger等主要是使用CAS保证数据的原子性操作,使用volatile保证数据的可见性来保证数据安全;
本文提到的东西比较浅显易懂,更多深入的,精彩的java方面的技术分享正在路上,需要的朋友敬请关注。。。