精华内容
下载资源
问答
  • WEB服务器会帮你把每个访问请求开辟一个线程,你只要按照你所开发的框架,比如tomcat会让你利用servlet这个框架来写代码。具体真的一言难尽,反正不用写到RUN中,除非你想对线程控制到极致,例如你要做测试。 2.部署...
        1. web应用中,要对某一个任务用多线程实现,最简单的代码格式是不是必须把要执行的代码放在run方法中?

        WEB服务器会帮你把每个访问请求开辟一个线程,你只要按照你所开发的框架,比如tomcat会让你利用servlet这个框架来写代码。具体真的一言难尽,反正不用写到RUN中,除非你想对线程控制到极致,例如你要做测试。


        2. 部署在服务器上的一个网站,多个浏览器在访问同一个功能点时,存在多线程之说吗?

        多个浏览器的意思如果是(无论多台电脑上还是同一台电脑上的)多个页面打开同一网站的某个功能页面,那么如第一个问题所说,每一次访问(即打开页面)都是一个请求,服务器会为每个请求开辟一个线程,就是多线程。


        3. 多线程和并发之间是怎么一种关系?

        多线程执行效率就是评判并发效果的好坏,高并发的概念就是在保证数据准确的情况下,减少进程所需操作的时间,特别经典的是页面访问服务器后,让服务器去修改数据库,如果你的数据库优化做的到位,那么查找数据并返回给客户端的时间将大大减少,我们知道对于一个热门网站的查询量是非常大的,然后一个服务器内存可以接收的进程数量也是有限的,这样一来,我们就说某一时间段内处理线程(访问请求)越多,那么并发效率就越好了。


        4. 对于经典的买票程序,是因为要操作共同资源而是用多线程技术,那么对于一些平常的查询显示功能就没必要用多线程技术。对于这里发起的多个查询请求,是多个线程吗?

        买票程序应用与WEB就应该是多线程,共同资源存放在数据库中,和第三个问题的回答类似,这种商业性的站点更侧重于保证数据准确性,有时候我们修改的某项值会影响到别人的查询与增删,于是意外情况就产生了,例如在一个A线程(用户)正在修改某项值(买票)的情况下,要减少1张的剩余票总量是不准确的,因为当这个用户在方法中对获得的总剩余票数的同时(以获得总剩余票数,但还未减一),另一个B线程(用户)也进行买票,那么B获得的总剩余票数与A是相同的,因此他们如果同时被允许操作数据库的公共资源,那么当两人都只想完购票的减一操作时,第三线程或其他线程的查询剩余票量将只会看到原本减少2张剩余量,实际只少了一张,可以想象如果操作的线程越多,误差将会更大。因此数据库才会有事务,锁等等概念来提高确保数据准确性前提下的并发效率


        5. 如何解决WEB开发多线程抢夺问题 —— synchronized

        Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

        1)当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

        2)然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

        3)尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

        4)第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

        5)以上规则对其它对象锁同样适用.


    展开全文
  • web应用中,每次请求都是不同的线程,因此,当对统一数据进行访问更新的时候,有可能会引发数据问题。 举个例子:有一个apple表,里面有个字段count,表示某种apple的数量。同时,后台提供获取这种苹果的服务,...

    在web应用中,每次请求都是不同的线程,因此,当对统一数据进行访问更新的时候,有可能会引发数据问题。

    举个例子:有一个apple表,里面有个字段count,表示某种apple的数量。同时,后台提供获取这种苹果的服务,获取苹果之后,就需要将count的值修改。

    假设apple表中有这么一条数据
    id      count
    12345   100
    ----------
    
    
        class Apple{
            int count;
        }
    
        public interface AppleMapper{
            @Select("select count from apple")
            Apple getApple();
    
            @Update("update apple set count = #{count}")
            void updateCount(int count);
        }
    
        service:
        public void getApple(int num) {
        //step1
        Apple apple = appleMapper.getApple();
        //取走num个苹果后剩下count个苹果,假设num<getCount()
        int count = apple.getCount() - num;
        //step2
        appleMapper.updateCount(count);
        }

    现在,有两条请求,都想获得苹果,req1.getApple(5)和req2.getApple(6);如果req1在step2完成后,req2才到达step1,那么数据库结果没有任何问题,但是,一旦req2在req1执行万step2时,就执行了step1,那么此时,req2.getCount() = 100,req1.count = 95,req2.count = 94,此时,无论哪个count存入数据库,都将是错误的,实际的count应该是89。

    解决办法:
    不要在业务逻辑中计算,然后将计算结果传入数据库,可传入需要改变的值,数据库sql改为”update apple set count = count + #{num}”。
    还有种不推荐的方法:以在stept1处获得的值作为条件,如果数据库的值和我在step1处取出的值一致,说明没有人修改这个值,那么就更新,否则不更新。

    这样的场景其实也不是很常见,一般前端将最终结果传入,只更新最终结果,就没这种问题了。最后,切记,遇到更新数值的操作时,不要在逻辑里计算,并将结果作为最终值更新,应该交由数据库去处理。

    展开全文
  • 它提供了JavaScript多线程解决方案 这个新特性叫做Web Worker (在此之前没有多线程,setTimeout等本质仍然是单线程) 虽然是多线程编程 不过我们不用担心传统的多线程语言C++、Java等等遇到的多线程问题 ...

    tip:有问题或者需要大厂内推的+我脉脉哦:丛培森 ٩( ‘ω’ )و

    【本文源址:http://blog.csdn.net/q1056843325/article/details/58642617 转载请添加该地址】

    不得不说,HTML5确实提供了大量强大的功能特性
    甚至颠覆了我们之前理解的JavaScript单线程
    它提供了JavaScript多线程的解决方案
    这个新特性叫做Web Worker
    (在此之前没有多线程,setTimeout等本质仍然是单线程)
    虽然是多线程编程
    不过我们不用担心传统的多线程语言C++、Java等等遇到的多线程问题
    下面我们就来看看什么是Web Worker
    #专用Worker
    专用Worker(Dedicated Worker)是最常用的Web Worker
    而且各个浏览器实现的还不错

    ##声明
    什么时候我们需要多线程呢
    比如说我们需要复杂的计算、

    //demo.js
    function calculate(){
      var ret = 0;
      for(var i = 1; i <= 1e9; i++){
        ret += i;
      }
      return ret;
    }
    var result;
    var start;
    var end;
    start = +new Date();
    result = calculate();
    end = +new Date();
    console.log(result); //500000000067109000
    console.log(end - start); //977
    

    我们计算了从1加到10亿的值
    让页面的渲染停了将近1秒钟
    对于用户的体验来说是相当不友好的
    虽然开发中不会有这么丧心病狂的计算
    但是可能会遇到密集而又复杂的任务
    这时我们也许会希望开辟一个独立的新线程来完成
    而我们只需要关注结果值


    HTML5允许我们使用Worker线程
    它的工作内容需要写在一个独立的js文件中
    让我们的多个程序块并发运行

    var worker = new Worker('scripts/worker.js');
    

    通过这种方式来实例化一个worker
    参数是js文件的路径(HTML主文件和Worker文件需要满足同源策略)
    当程序运行到这里时
    这个文件就会被加载到一个Worker中
    浏览器就会启动一个独立线程运行该js文件

    ##交互
    我们的主线程和工作线程是基于事件的机制来进行交互的
    换句话说,
    它们都需要订阅事件来互相通信(onmessage事件)

    //主线程
    worker.addEventListener('message', function(e){
    	//e.data为从worker线程得到的数据
    });
    worker.possMessage(...);//向worker线程发送数据
    
    //工作线程
    addEventListener('message', function(e){
    	//e.data为从主线程得到的数据
    });
    possMessage(...);//向主线程发送数据
    

    它们的数据绑定和数据发送时类似的
    只不过在worker文件中不需要用对象调用API
    这样我们刚才的复杂计算就可以让worker来做

    //worker.js
    function calculate(){
      var ret = 0;
      for(var i = 1; i <= 1e9; i++){
        ret += i;
      }
      return ret;
    }
    postMessage(calculate());
    
    //demo.js
    var worker = new Worker('scripts/worker.js');
    worker.addEventListener('message', function(e){
      console.log(e.data); //500000000067109000
    }, false);
    

    在HTML5的Web Worker规范中
    worker中还可以实例化它自己的worker(感觉没什么必要啊)
    称为subworker(线程嵌套线程)
    不过我测试了一下,chrome暂时还不支持subworker
    但是据说Firefox支持
    ##终止
    既然我们可以创建worker
    那么我们也应该可以终止worker让它停止工作
    在主线程和工作线程中都可以终止
    只需要在worker对象或worker的作用域中调用API
    一个是我们让它结束工作
    一个是它自己罢工

    //主线程
    worker.terminate();
    
    //工作线程
    close();
    

    不过我想我们一般情况下
    都会以worker对象上调用terminate方法的来终止它
    这样会比较安全
    ##环境
    最开始的时候我就说了
    我们不必担心传统的多线程语言遇到的多线程问题
    比如说为了防止它们抢占资源而引入的…
    无比复杂的锁机制
    为什么呢?
    因为在worker内部
    我们根本就不能访问主程序的任何资源
    它就是一个完全独立的线程
    Web Worker有如下限制:

    • 同源策略限制
    • 不能访问页面DOM和其他资源
    • 浏览器实现程度不同

    不过我们可以在worker内部做这些事情:

    • 可以执行网络操作(Ajax、Web Sockets)
    • 可以使用定时器(set/clearTimeout()、set/clearInterval())
    • 访问某些重要全局变量及功能的复本(navigator、location、JSON、applicationCache)
    • 可以使用importScrips()加载额外js脚本
    importScripts('foo.js','bar.js');
    importScripts('foobar.js');
    

    好奇的话,可以在worker内console.log(this);
    查看它的作用域内都有什么
    ##应用
    关于它的应用
    我们会利用Web Worker做这些事情

    • 复杂数学计算
    • 复杂数据排序
    • 数据处理(压缩、图像处理…)
    • 高流量网络通信

    #共享Worker
    除了专用线程外还有一个共享线程Shared Worker
    可以了解一下
    刚刚我查了一下
    到目前为止,只有谷歌、火狐还有欧朋实现了这个技术


    如果我们的网站或者App可以同时加载多个tab(标签页)
    那么如果使用普通的worker我们可能会重复创造多个线程
    这必然会占用系统资源
    这时如果我们可以让App或整站的页面实例都能够共享一个worker
    那就很棒了~
    共享线程和专用线程使用方式差不多,稍微复杂一点点而已

    var worker = new SharedWorker('scripts/worker.js');
    

    由于共享线程需要与多个程序实例或页面链接
    所以它需要通过某种方式来了解消息的来源
    这个方式就是利用一个唯一标识符port(端口)
    这样我们刚才的例子就需要写成这个样子

    //demo.js
    var worker = new SharedWorker('scripts/worker.js');
    worker.port.addEventListener('message', function(e){
      console.log(e.data); //500000000067109000
    }, false);
    worker.port.start();
    

    在主线程中
    端口连接必须初始化
    使用API worker.port.start();

    //worker.js
    function calculate(){
      var ret = 0;
      for(var i = 1; i <= 1e9; i++){
        ret += i;
      }
      return ret;
    }
    addEventListener('connect', function(e){
      var port = e.ports[0];
      port.start();
      port.postMessage(calculate());
    });
    

    在共享worker内部同样需要初始化端口连接port.start();
    除此之外,我们还需要处理额外事件onconnect
    这个事件为我们的特定连接提供了端口对象
    var port = e.ports[0];用于获取连接分配的端口


    我们的onmessage事件就可以写在onconnect事件处理函数内部

    addEventListener('connect', function(e){
      var port = e.ports[0];
      port.addEventListener('message', function(e){
    	...
    	port.postMessage(...);
    	...
      });
      port.start();
    });
    

    除此之外,其他的功能共享Worker和专用Worker都是一样的


    [==主页传送门==](http://blog.csdn.net/q1056843325)
    展开全文
  • 开发线程安全的Spring Web应用

    千次阅读 2005-01-17 16:45:00
    前言 如果开发者正开发或维护基于Servlet的Web应用,则Servlet规范建议最好能够看看。因为它含有的内容对于Web应用开发者理解Servlet容器的工作机理很有帮助。 其中,规范给出了Servlet容器是如何处理客户请求的。...

      前言

      如果开发者正开发或维护基于Servlet的Web应用,则Servlet规范建议最好能够看看。因为它含有的内容对于Web应用开发者理解Servlet容器的工作机理很有帮助。

      其中,规范给出了Servlet容器是如何处理客户请求的。Servlet容器将会根据web.xml配置文件中定义的各个Servet而创建相应的单例。因此,多个客户请求可能同时访问这些单例,即多个线程同时访问它们。在Web应用中保证线程安全是很重要的。开发者应该对这个问题保持警惕,而且必须确保各自的代码必须以线程安全的方式运行。

      温习线程安全

      大部分Java开发者都应该听过synchronized关键字。在不采用任何第三方库的前提下,Java本身对线程提供了原生支持,而且synchronized关键字往往是Java应用中实现线程安全最重要的因素。Java中的同步提供了互斥支持。通过同步一块代码或整个方法能够保证同时最多只有单个线程执行它,从而实现了线程安全。引入同步具有副作用,即阻塞。比如,大公司或律师办公室的前台小姐同时需要处理电话、邮件、受访客户等等。这使得她的工作很繁忙,而且导致一些事情不能够及时处理。

      在Web应用中需要警惕阻塞。受同步保护的代码块使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态,除非某客户处理完成。而且互斥不仅会带来阻塞,还会带来死锁。通常,死锁是不可恢复的。如下条件将触发死锁的发生:线程A锁住了线程B等待的资源,而且线程B锁住了线程A等待的资源,即线程B一直在等待线程A释放锁,线程A也是如此。因此,对于多线程的应用而言,死锁的预防和处理通常都是很头疼的。

      另外,synchronized关键字还使得大量的同步对象到处使用,从而引入了死锁的可能性。比如,java.util.Hashtable和java.util.Vector中提供的方法都是受互斥保护的,因此除非确实需要使用它们,否则尽量不用。开发者只需要使用java.util.HashMap和java.util.ArrayList即可。当然,java.util.Collections中的同步方法也使用了synchronized关键字。

      尽管可重入更易于管理,但它引入了其他问题。可重入代码避免了线程间数据的共享。考虑如下代码(姑且认为Java中的方法是线程安全的):

    public Double pi() {
     int a = 22;
     int b = 7;
     return new Double(a / b);
    }

      不管同时进入该方法的线程有多少,它总是线程安全的。各个线程都维护了属于各个线程的栈,并不同其他线程共享。其中,各个线程在当前方法(包括静态方法)中创建的方法变量仅属于当前线程,即存储在当前线程的栈中。因此,当线程A和B同时进入上述方法时,它们都将创建a和b。由于上述方法不存在数据共享,因此上述方法是线程安全的。请注意:22/7值同PI值较接近,但它们不相等。

      接下来,看看如何优化上述代码吧。

    private Double pi = null;

    public Double pi() {
     if (pi == null) {
      pi = new Double(22 / 7);
     }

     return pi;
    }

      尽管改进后的方法能够提高性能,但并不是线程安全的。比如:如果pi为null,而且线程A和B同时进入第4行。因此,线程A和B会同时测试pi是否为空,它们都将返回true。接下来,如果线程A继续执行(线程B由于某种原因被暂挂),然后返回对内存地址的引用。其中,该内存地址含有22/7的结果,即pi值。最后,线程A退出方法。当线程B再次进入第5行时,新的内存地址将覆盖原先的内存地址(线程A提供的)。这太危险了,而且这种问题往往难于调试。

      如果使用ThreadLocal,则不仅能够保证pi()方法是线程安全,而且能够提供性能的改善。 private static ThreadLocal pi = new ThreadLocal();

    public Double pi() {
     if (pi.get() == null) {
      pi.set(new Double(22 / 7));
     }
     return (Double)pi.get();
    }

      ThreadLocal类能够包裹任何对象,而且能够将对象绑定到当前线程,使得它仅仅供当前线程使用。当线程初次执行pi()方法时,由于没有对象绑定到ThreadLocal实例pi上,因此get()方法返回null。借助于set()方法能够将对象绑定到当前线程,而且不供其它线程使用。因此,如果不同线程需要经常访问pi()方法,则借助于ThreadLocal不仅能够保证线程安全,而且能够提高性能。

      目前,存在很多关于如何使用ThreadLocal的资源。在Java 1.4之前,ThreadLocal的性能确实很差,但是现已解决了这个问题。另外,由于对ThreadLocal的错误理解,使得很多开发者对它的误用。注意,上述实例使用ThreadLocal的方式是绝对没问题的。在引入ThreadLocal后,上述方法的行为并未发生改变,但是方法已经是线程安全的了。

      通过可重入的方式开发线程安全的代码要求开发者谨慎使用实例变量或静态变量,尤其对于修改那些其他线程需要使用的对象而言。某些场合,使用同步可能更为合适。然而,为识别由于同步而引起的应用性能瓶颈往往只能借助于专业的性能评测工具或负载测试完成。

      Web应用中的线程安全

      在温习线程安全的知识后,来研究Web应用中是如何线程安全的吧!开发者通过创建Web页面来操作数据库。比如,在Web层和业务逻辑层都能够操作RDBMS。本文使用Hibernate将业务模型持久化到数据库中。在Web层,开发者可以使用Tapestry、Wicket、Struts、WebWork、JSF、Spring MVC,或者其他运行在Web容器中的Web框架。

      至于Web层的具体实现并不是本文的重点。本文将关注如何管理数据库连接,这也是Web应用中处理线程安全问题是经常要考虑的资源。数据库连接对象,比如连接、结果集、Statement、Hibernate Session,是有状态对象。当然,它们不是线程安全的,因此不能够同时供多个线程访问。在本文前面已经提到,开发者应尽量避免使用同步。无论是synchronized关键字,还是那些同步类(Hashtable或Vector),应尽量避免使用。因此,如果使用可重入,则不用处理阻塞或死锁。

      当然,通过可重入实现线程安全以访问数据库并不是件简单的工作。比如,有些开发者可能会在Servlet容器配置中添加过滤器。因此,在客户请求到来时,过滤器将创建JDBC连接或Hibernate Session,并借助于ThreadLocal类将它们绑定到当前线程中,从而供业务逻辑使用。如果直接使用J2EE API,则开发者除了需要做很多同业务逻辑无关的操作外,还需要管理事务、DB错误等等开发内容。请注意,这些同业务逻辑无关的操作的维护工作往往很费时间。

      Spring的闯入

      一些Java开发者可能听说过Spring提供的DAO抽象。当然,一些开发者也有可能使用过它。借助于Spring提供的模板,开发者能够使用DAO代码的重用。借助于Spring AOP,开发者还能够使用声明式事务。因此,本文来研究Spring是如何实现以线程安全方式访问RDBMS的。比如,Spring允许以JDBC、Hibernate、JDO、iBATIS、TopLink等方式访问数据库。如下给出的实例是企业应用中很常见的情景。

      首先,定义数据源和用于Hibernate SessionFactory。

    <bean
    id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
    <list>
    <value>WEB-INF/jdbc.properties</value>
    </list>
    </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
    <property name="url"><value>${jdbc.url}</value></property>
    <property name="username"><value>${jdbc.username}</value></property>
    <property name="password"><value>${jdbc.password}</value></property>
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
    <property name="dataSource">
    <ref bean="dataSource"/>
    </property>
    <property name="mappingDirectoryLocations">
    <list>
    <value>classpath:</value>
    </list>
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">net.sf.hibernate.dialect.HSQLDialect</prop>
    <prop key="hibernate.show_sql">true</prop>
    </props>
    </property>
    </bean>

      这是使用Hibernate的典型配置,即通过定义的数据源连接到数据库、通过本地SessionFactory创建Hibernate SessionFactory。接下来,需要定义业务对象(实现对DB的访问)和事务管理器(通过Hibernate Session管理本地事务)。其中,业务对象暴露的方法能够在数据库中添加新的纪录,而事务管理器能够将方法包裹在事务中。它们的定义如下。

    public interface CustomerDAO {
    public void createCustomer(Customer customer);
    }

    public class HibernateCustomerDAO implements CustomerDAO {

    private HibernateTemplate hibernateTemplate = null;

    public void setSessionFactory(SessionFactory sessionFactory) {
    this.hibernateTemplate = new HibernateTemplate(sessionFactory, false);
    }

    public void createCustomer(Customer customer) {
    this.hibernateTemplate.save(customer);
    }
    }

      开发者应该已经看到,上述类使用了Spring提供的HibernateTemplate。注意,模板的开发遵循了业界最佳实践,并且将一些同业务不相关,但J2EE API规定要处理的那些代码处理掉了。与此同时,它通过DAO抽象将受查异常转换为非受查异常。当然,Spring不只是为使用Hibernate提供模板,它还为JDBC、iBATIS、SqlMap、JDO、TopLink提供类似模板。由于这些模板类及其实例变量实现了可重入,即都是线程安全的,因此允许并发线程同时使用模板。使用这些模板不仅能够实现代码的重用,还提供了最佳实践。除了以线程安全方式访问DB外,模板还提供了其他很多有意义的内容。好了,来看看如何定义业务对象和事务管理器吧!

    <bean id="customerDAOTarget" class="test.usecase.HibernateCustomerDAO">
     <property name="sessionFactory"><ref bean="sessionFactory"/></property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
     <property name="sessionFactory"><ref bean="sessionFactory"/></property>
    </bean>

    <bean id="customerDAO" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
     <property name="transactionManager"><ref bean="transactionManager"/></property>
     <property name="target"><ref bean="customerDAOTarget"/></property>
     <property name="transactionAttributes">
      <props>
       <prop key="create*">PROPAGATION_REQUIRED</prop>
       <prop key="*">PROPAGATION_REQUIRED</prop>
      </props>
     </property>
    </bean>

      如果开发者对Spring中事务管理的配置不熟悉,则本文正好满足你们。首先,上述Spring配置片断定义了业务对象HibernateCustomerDAO,它包裹了Hibernate SessionFactory。注意,默认时,Spring中定义的JavaBean都是单例的,HibernateCustomerDAO也不例外。这意味:多个线程可能同时执行createCustomer()方法。

      其次,配置了Hibernate事务管理器,它包裹了同一Hibernate SessionFactory实例。在事务管理器每次执行时,它都会完成如下几件事情。其一,检查Hibernate Session是否绑定到当前线程。如果已绑定,则直接使用它。如果还未绑定,事务管理器将告知Hibernate SessionFactory创建新的Session,然后将创建的Session绑定到当前线程。其二,如果当前没有处于活动的事务,则事务管理器将启动新的事务,并将Session包裹进来。否则,直接参与到活动事务中。

      整个过程是通过使用Spring提供的TransactionProxyFactoryBean实现的。当然,这是一种以声明方式实现的事务管理过程。 TransactionProxyFactoryBean能够为业务对象创建代理对象,从而通过事务管理器管理事务。当每次通过代理对象调用createCustomer()方法时,事务管理器将根据事务属性管理事务。当前,Spring除了提供HibernateTransactionManager事务管理器外,还为JDBC数据源、JDO、TopLink提供了相应的事务管理器。

      再来看看业务对象吧!当调用createCustomer()方法时,HibernateTemplate将查找绑定到当前线程的Hibernate Session。由于上述配置文件片断传入到HibernateTemplate构建器的第二个参数为false,因此如果没有绑定Hibernate Session,则将抛出未受查异常。这对于那些未正确配置事务管理功能的场和特别有用(注意,事务管理器很重要)。一旦事务管理配置好后,Hibernate Session将绑定到当前线程,从而启动事务。请注意,HibernateTemplate不会去检查事务是否激活,也不会显示地启动或终止事务。也请注意,如果在声明的方法(事务属性中给出的)中抛出了未受查异常,则当前活动事务将回滚。

      结论

      最后,来总结一下Spring以线程安全方式实现数据访问吧。通过使用事务管理和权衡ThreadLocal提供的功能,Spring将数据库连接(JDBC连接、Hibernate Session、JDO持久化管理器)绑定到当前线程,从而供DAO模板使用。本文在最开始研究了数据库连接并没有在线程间共享。Spring不仅提供了声明式事务管理、J2EE API抽象、最佳实践,而且其提供的模板是线程安全的。当使用Spring访问DB时,通过可重入实现应用的线程安全是最为可靠、常见的做法。

    展开全文
  • 最近的项目是关于B/S架构下的Web版PACS开发,为了缩短研发周期,采用了该领域主流的两大开源库:DCMTK和CxImage。但是由于项目初期对CxImage开源库的编译问题,导致该开源库在MFC下无法正常运行,因此决定将功能函数...
  • java-web之servlet中的线程安全问题

    千次阅读 2016-07-25 00:01:14
    线程池实际上是等待执行代码的一组线程叫做工作者线程(Worker Thread),Servlet容器使用一个调度线程来管理工作者线程(Dispatcher Thread)。 当容器收到一个访问Servlet的请求,调度者线程从线程池中选出一个
  • 简要回顾几天来的工作,又解决了一些基础性问题:1. 完成背景图像窗口的淡入淡出(fade in, fade out),,实际上并不复杂,调用AnimationWindow函数后,需要正确处理WM_PRINTCLIENT消息,才能顺利完成窗口贴图并产生...
  • Java开发购物商城类项目出现多线程高并发怎么处理?求解,感谢。
  • Web项目中关闭线程

    千次阅读 2013-02-21 11:48:04
    Weblogic的update和stop/start的区别   通过进程实现一个黑名单缓存机制时,...开发阶段为了方便,基本上都是重启weblogic服务器,没有发现这个问题。   问题的缘由: 对weblogic的webapp执行 stop/start时
  • setTimeout解决GUI渲染线程阻塞问题

    千次阅读 2017-08-27 19:04:22
    我还记得我第一次用这个函数的时候,我天真的以为它就是js实现多线程的工具.当时用它实现了一个坦克大战的小游戏,玩儿不亦乐乎.可是随着在前端这条路上越走越远,对它理解开始产生了变化.它似乎开始蒙上了面纱,时常有...
  • Web开发问题

    千次阅读 2009-12-06 18:01:00
    其它所有问题都是这个问题的某种解决方案引入的. 这个论断有一个推论, 就是不需要识别用户的Web应用是最简单的Web应用. 一种方案是所有的业务都设计成一次请求就可以完成, 比如让用户每次都输入用户名密码, 填写所有...
  • Spring使用ThreadLocal解决线程安全问题

    千次阅读 2015-01-07 12:33:52
    我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager...
  • 关于django多线程问题解决

    万次阅读 2012-10-25 15:48:51
    Django自带的Development Server作为调试开发时的临时服务器是一个非常方便的工具,因为避免了在还没有代码之前就需要配置一大堆环境的麻烦。 但是此服务器也有一个不足的地方就是它是单线程模式的,也就是同时只能...
  • Web应用架构演进 WEB应用架构演进过程,系统对于性能和稳定性方面需要解决问题
  • Android平台调用Web Service:引入线程

    千次阅读 2014-05-19 21:16:36
    android 3.0+以上 已经不建议在activity中添加耗时操作,要界面和数据脱离。4.0以上的通信都必须放到线程里去做,不能在UI线程解决办法是另起线程,如果一定要想在UI线程操作
  • 有着强大的Web Service处理能力,但现在关于如何用BCB创建和调用Web Service的资料并不多,现在我就示范一下如何使用BCB6.0实现一个简单的Web Service客户端,而且在我的例子中使用的是多线程的调用方式。...
  • ,以帮助开发实现更好的并发控制。 线程通信 线程通信的目标是使线程间能够互相发送信号。另一方面,线程通信使线程能够等待其他线程的信号。 例如,线程B可以...
  • Java Web服务收到请求时线程的情况

    千次阅读 多人点赞 2017-05-07 17:29:15
    Web请求线程的状态在开发中,突然想到了这样的一个问题, Java对每一次Web的请求,是否都会创建一条线程去进行处理呢?也就是说,当一个Class的方法同时有1000个请求访问时,线程是如何运作的呢?解释上面的问题,...
  • Spring Web应用的线程安全

    千次阅读 2011-08-01 10:37:33
    Spring Web应用的线程安全 前言 如果开发者正开发或维护基于Servlet的Web应用,则Servlet规范建议最好能够看看。因为它含有的内容对于Web应用开发者理解Servlet容器的工作机理很有帮助。  规范中最有趣的一部分...
  • struts线程问题

    千次阅读 2010-12-31 09:41:00
    struts线程问题
  •  2:spring单例模式的安全问题是使用ThreadLocal解决的 单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 当多用户同时请求...
  • 昨天操作WebAPI的时候由于涉及到主线程(UI线程)与子线程之间的通信时采用Thread创建子线程,并复写 public void run()方法时,因为run()方法的返回值 类型是void的,所以操作无法把执行完成之后的数据返回给...
  •  对于经常使用第三方框架进行web开发的程序员来说,Java线程池理所应当是非常智能的,线程的生命周期应该完全由Java本身控制,我们要做的就是添加任务和执行任务。但是,最近做文档批量上传同步时发现线程池中的...
  • Servlet开发细节-线程安全当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的...使用同步块可以解决线程安全问题,但是会使并发串行化。如果某个Servlet实现了SingleThreadModel接口,那么Servlet引
  • 在接下来的几个月时间里,我打算写一系列关于完整web开发的文章。这第一篇文章虽然有所粗略,但也能够充分概括了在之前15年或者更久的时间里web应用程序如何进行演变。并且最后我会囊括下这段时间内所写的相关技术。...
  • 首先简单说下:servlet是单例的,每个用户访问都会生成一个线程为其处理。然而servlet的是单例的。也就说一个servlet只能生成一个对象,这样多个线程操作一个实例对象,必然可能造成线程不...这种情况有两种解决办...
  • web开发入门

    千次阅读 2011-06-29 20:05:00
    以前无论在nokia还是tencent都是做移动客户端开发,那时候也都是用编译型的c++语言。...问题是:没有几本书可以把相互之间的关系解释清楚,比如:webserver和php脚本的关系;php底层实现;mysql底层
  • servlet 多线程问题

    万次阅读 2011-10-19 10:24:37
    介绍了Servlet多线程机制,通过一个实例并结合Java 的内存模型说明引起Servlet线程不安全的原因,给出了保证Servlet线程安全的三种解决方案,并说明三种方案在实际开发中的取舍。  关键字:Servlet 线程安全 ...
  • 2021年Django Web开发框架依然值得选择吗?

    千次阅读 多人点赞 2020-12-01 16:28:40
    需要使用UWSGI或Gunicorn创建足够多的运行django的工作线程来为流量提供服务,这要比node.js或FastAPI之类的解决方案效率低下且资源消耗更多,后者运行事件循环(event loop)并在需要等待时在请求之间切换任何事情...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 182,294
精华内容 72,917
关键字:

web开发需要解决线程问题吗