为什么tornado的并发性能不及java servlet例子

标签:至少1个,最多5个
java开发中不可避免用到多线程情况,比如web中常见的Servlet、Struts2都是运用到多线程,多线程的根本目的是为了更快的执行。其他常用到的多线程比如设计到大量I/O操作,用多线程可明显提升效率。java中最基础的并发类就是Runnable.class,Runnable是一个接口,只要实现实现Runnables,重写方法run() 就可以实现多线程操作。
举个实现Runnable的例子:
public class LiftOff implements Runnable {
protected int countDown = 10; // Default
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {}
public LiftOff(int countDown) {
this.countDown = countD
public String status() {
return "#" + id + "(" +
(countDown & 0 ? countDown : "Liftoff!") + "), ";
public void run() {
while(countDown-- & 0) {
System.out.print(status());
Thread.yield();
public static void main(String[] args) {
Thread t1 = new Thread(new LiftOff());
t1.start();
从这个例子中,可以看出在java中多线程的实现多线程是很简单的事,但是多线程的学习是易懂难通,会遇见死锁、逻辑混乱等各类问题,所以使用多线程必须慎之又慎。Runnable之后有一个基础的并发类就是Thread.class,Thread就是实现了Runnable的一个类,但是在Runnable的基础上新增了一些方法包括:线程优先级、后台线程、分组、命名等,还是非常实用的。
因此我们一般使用多线程可以实现Runnable.class或者继承Thread.class.一般使用Runnable即可这样还可以继承其他类
好了本次文章就到这来,简单地说明了java多线程的一些知识,下次会关于多线程方法更深入的阐述。
0 收藏&&|&&3
你可能感兴趣的文章
24 收藏,221
51 收藏,7.6k
73 收藏,5.7k
分享到微博?
明天提醒我
我要该,理由是:Servlet不是线程安全的。
要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的。
当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象并进行初始化,之后调用service()方法。要注意的是每一个Servlet对象再Tomcat容器中只有一个实例对象,即是单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。
上图中的Thread1和Thread2调用了同一个Servlet1,所以此时如果Servlet1中定义了实例变量或静态变量,那么可能会发生线程安全问题(因为所有的线程都可能使用这些变量)。
比如下面的Servlet中的 name 和 i变量就会引发线程安全问题。
import javax.servlet.ServletE
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import java.io.IOE
import java.text.SimpleDateF
import java.util.D
public class ThreadSafeServlet extends HttpServlet {
public static String name = &Hello&;
//静态变量,可能发生线程安全问题
//实例变量,可能发生线程安全问题
SimpleDateFormat format = new SimpleDateFormat(&yyyy-MM-dd hh:mm:ss&);
public void init() throws ServletException {
super.init();
System.out.println(&Servlet初始化&);
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.printf(&%s:%s[%s]\n&, Thread.currentThread().getName(), i, format.format(new Date()));
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.printf(&%s:%s[%s]\n&, Thread.currentThread().getName(), i, format.format(new Date()));
resp.getWriter().println(&&html&&body&&h1&& + i + &&/h1&&/body&&/html&&);
在Tomcat中启动这个Servlet并在浏览器发起多个HTTP访问,最后会发现变量 i 是多线程共享的。
如果需要更加深入透彻地了解Tomcat接收HTTP的细节,以及与Servlet交互的细节,可以深入看看Tomcat的架构和源码。
阅读(...) 评论()编程语言API性能大比拼
发表于 15:36|
作者夏梦竹编译
摘要:Ciaran是Skimlinks项目团队中的一名领导者,热爱开发,在业余时间喜欢研究一门新语言。作者和他的团队在开发Skimlinks项目时遇到了一些困难,于是做了这份调查表,文中将Node.js、Scala、Go、Python、PHP进行对比,最终Python获胜,目的的是为了让开发者为stack挑选最好的开发技术。
Ciaran是Skimlinks项目团队中的一名领导者,热爱开发,在业余时间喜欢研究一门新语言。作者和他的团队在开发Skimlinks项目时遇到了一些困难,于是做了这份测试,文中将Node.js、Scala、Go、Python、PHP进行对比,最终Python获胜,目的的是为了让开发者为stack挑选最好的开发技术。
在过去的这段时间里,我之所以杳无音讯,是因为作为这个项目的领头人,我正从事一项有趣的项目,我们将其命名为&Skimlinks&。
我的大部分工作是从事后端引擎开发和支持SkimWords产品进程,通过一些非常完美的高科技进行识别和添加代销商网络产品链接从而让网站主获取利润。这是一种新颖的线上广告模式,相比于页面上的大幅banners图我更喜欢这种新颖的模式,我们正在尝试为用户添加有价值的信息如产品价格比较、添加链接让用户可直接购买想要的产品。
开发环境:
大部分前端开发是用PHP编写的,当公司需要快速、灵活开发项目时,选择PHP是个不错的选择。但是随着公司既定产品的知名度不断提高以及搜索的高并发访量,PHP正日益成为我们发展的一个瓶颈。
存在问题:
使用Apache多选程模块(MPM),apache会阻碍大量的搜索请求,当出现高并发访量时,页面无法响应。
这里有一个快速的方法可提高服务器的吞吐量增加工作进程,然而当RAM快要耗尽时,将会受到限制。每个进程都有独立的RAM数据块,增长和搜索取决于PHP在哪个点上,当没有足够的空间释放时,你必须将OOMing关闭(它可以迅速的将吞吐量降至为0)。
最可行的扩大规模的方法就是把项目管理模块从Apache prefork MPM换成更出色、更快速的Apache worker MPM。通过改变多进程大大增加了服务器请求数,唯一的缺陷只是为了这个工作而工作,PHP必须能够保证处理多个并发线程不会产生死机,然而事实并非如此。PHP的核心是多线程,因此我门认为它可能是因为某些驱动或者延长使用而导致失败,然而无论出于什么原因,PHP不在符合我们的需求。
为此,引发了我们会选择哪种语言进行开发而争论不休,每个人都在推崇他们喜欢的语言,有人赞成、有人反对。很明显,众口难调,没有一个衡量标准是很难选出来的,因此,我们决定用各个语言来测试一个系统,看它们的执行情况在做定夺。
参赛语言:
基本规则是,如果你想要某语言进行测试必须愿意提供执行API请求数,最后推选出:
Node.js:流行程度依然高涨,它的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处理数万条同时连接到一个(只有一个)物理机的连接代码。&
Scala (w/ Tomcat):我非常热爱JVM,起初我也推荐过该语言,但因为它过于冗长而被否决,令人兴奋的是,这次Scala得到了大家的认可。
Python (w/ Tornado):我们已经有Python方面的经验。
Go (golang):我对这门语言感兴趣,而我的同伴们却认为这门语言不好,建议使用Java。我还建议使用C#和.NET/mono,但因为不公平性,最后都被否定了。
我们选择了一个非常简单的日志API系统,所做的这些是为了从JSON请求数中抓取详细信息,采用MD5,用于确保信息传输完整一致。(主流编程语言普遍都用MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理)每个执行阶段都将使用Apache Benchmark(Apache附带的一个小工具,专门用于HTTP Server的benchmark testing,可以同时模拟多个并发请求)来评估各种语言开发并发水平速度。
当Node.js和Python Tornado以单一线程运行时,使用Nginx(一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器 )来查看这两个实例。
针对Scala我甚至特意编写一份old-school Servlet(一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面,它担当客户请求Web浏览器或其他HTTP客户程序与服务器响应的中间层)在基于tomcat下运行。
采用AWS(Asp Web Server是一款基于netbox开发的asp web服务器,其个小功能强大,基本上能够取代IIS成为广大Asp程序员和网站开发者的利器)直接在服务器上执行基准,以消除任何一个网络瓶颈。
通过mongo删除每次测试数据,每次测试至少执行3次,选取平均值,以确保有足够的&热身&时间和消除任何异常结果。
通过在多个并发值下进行测试((10,50,100,200,500,1000),一起来看下在高负荷的情况下,性能发生了什么变化。
测试结果:
每秒请求数:这个测试给了我们一个实现纯速度的想法,最明显的一点(越高越好)。
有一点值得我很欣慰,Scala独占鳌头。PHP(正如预期所想的那样)受多线程的限制,香消玉损。另一个让我震撼的是Go语言当并发访量不断增加时,它以平缓的速度迅速下滑,最终也Over了。如期所料,两个单线程non-blocking solutions(node和 python)性能差不多,python要比Node稍微好点。
响应时间:
尽管每秒请求数进程的吞吐量呈现出一个好的迹象,但是同样重要的是在高负荷的情况下,表现很糟糕。由图表得知,在一段时间内完成的请求数比例,越低越好。
100并发请求数:
在这里,我们看到Scala需要的时间最少,而其他几门语言之间没有太大区别。
200并发请求数:
图中,我们看到有趣的现象,以9秒速度来计算请求数,Go和PHP都有受到影响,花费的时间比较多。
500并发请求数:
在500并发需求时,使用9&14秒完成请求。PHP无法响应,Go语言花费时间较多,占最高值。
1000并发需求数:
当我们遇到数以千计的请求数时, Go语言Over了,通过测试,根据apache规则要求超过50%的失败率就算出局。如图所示Node和Python依然存在,可以清楚的看到其性能特性。但是Python比Node要更好一点。但在第一幅图上,Python表现的要稍微差一点。
通过测试,能清楚的分辨出各语言的性能表现,以上测试的这些数据是我们APIs中的一部分,因此对我们来说非常重要。
Scala表现的很好,几乎很完美,我把它归功于在连接池的Mongo数据库中单独接入MessageDigests和快速进行JSON分析程序。我不确定Go语言到底是怎么了,也许是我使用的Mongo驱动的问题,但无论是什么原因,看到它这么差的表现真的让我很难过。
最后决定:
最终,我们经过讨论决定选择Python!Scala如此之快,我们为什么不选择Scala而另选Python呢?原因如下:
Scala这门语言很难,我需要很久才能将简单的API整合在一起,才能进行工作,python阅读起来就像,而Scala阅读就像蛇类游戏一样。
线性编程是很痛苦的,对Scala来说,很容易也很安全,简单的单线程non-blocking解决方案总是很吸引人,但我们应该不断的去尝试挑战。
整个团队在Python上有着丰富的经验,如果让大家去接受一门新的语言,尤其像Scala这样的既昂贵又费时间。
此前网络速度、数据库查询等API成为我们发展的一个瓶颈,而今,我们已经找到正确的解决方案&&Python,我们只需等待执行和发布,希望这个决定是正确的。
英文出自:
(本文为CSDN原创,未经授权或许可,不得转载)
推荐阅读相关主题:
网友评论有(0)
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章高并发、高性能的servlet请求处理方案咨询 - ITeye问答
本人需要做一个HTTP服务器,提供servlet服务给多个设备(10万个以上)进行请求,想问一下高并发、高性能的servlet请求处理有什么好的处理方案,例如利用jetty作为http服务器?或者有什么好的集群方案?
万分感谢。
目前还没有答案
已解决问题
未解决问题Servlet的生命周期是由Servlet容器来负责的。
Servlet容器通常采用单实例多线程的方式,减少Servlet创建实例的开销,提高效率。
当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类(如果设置了on-start-up,启动时就会实例化)。当又有新的客户端请求该servlet时,一般不会再次实例化该servlet类,也就是有多个线程在同时使用这个servlet实例。
因此,当有两个或多个线程同时访问一个Servlet时,可能会发生多个线程同时访问同一资源的问题。
Servlet的线程安全问题主要是由于Servlet实例变量使用不当导致的,例如:
public MyServlet extends HttpServlet{
实例变量 output;
public void service(ServletRequest request, ServletResponse){
对实例变量output的操作;
// 可能导致同步问题
对局部变量username的操作; // 不会导致同步问题
Servlet实例的JMM(Java Memory Model)模型:
根据JMM,系统存在一个主内存,Java中所有实例变量都存储在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存,工作内存由缓存和堆栈组成:缓存中保存的主存中变量的拷贝,缓存可能并不总和主存同步,也就是缓存中变量的修改可能没有立刻写到主存中;堆栈中保存的是线程的局部变量,线程之间无法相互直接访问堆栈中的变量。
避免同步问题
避免使用实例变量(主要使用方法)
同步代码块synchronized
使用SingleThreadModel接口(废弃)
本文已收录于以下专栏:
相关文章推荐
新建一个线程类,在线程中获取配置属性文件:包含小集群中所有的主机地址,还可以配置秘钥对;
通过过滤器,过滤掉本机的地址(也可以不过滤,本机有修改的时候,直接发通知,本机也进行修改),
在线程中遍历地址...
ServletContext和Web应用关系:
当servlet容器启动Web应用,并为每个Web应用创建唯一的ServletContext对象。可以吧ServletContext看成一个Web应用...
在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。
一、表单...
主要使用application, listener, 把用户id和用户对象放到ConcurrentHashMap中,再存入application中
1、登录时把id和对象放到applicat...
ServletContext和Web应用关系:
当servlet容器启动Web应用,并为每个Web应用创建唯一的ServletContext对象。可以吧ServletContext看成一个Web...
并发问题的产生
在Internet中,一个Web应用可能被来自四面八方的客户并发访问(即同时访问),而且有可能这些客户并发访问的是Web应用中的同一个Servlet。Servlet容器为了保证能同时响...
Servlet/JSP 技术和ASP,PHP等相比,由于其多线程运行而具有很高的执行效率。
Servlet/JSP 默认是多线程模式执行的。
servlet是单实例的,
ktv,包间,订单
在ktv针对具体包间下单时,是需要加锁去实现的,不然有可能同一个包间同时产生2个订单
但是锁加在哪里?加在包间对象?NO!
因为“包间”对象从数据库里查询出来的,...
他的最新文章
讲师:王哲涵
讲师:王渊命
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 jsp servlet javabean 的文章

 

随机推荐