首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java 线程安全小结

2013-11-09 
java 线程安全总结java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线

java 线程安全总结

java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改。java内存模型主要分为可见性和有序性1.可见性:多个线程之间是不能互相传递数据通信的,它们之间的沟通只能通过共享变量来进行。Java内存模型(JMM)规定了jvm有主内存,主内存是多个线程共享的。new一个对象时会被分配在主内存中,每个线程都有自己的工作内存,工作内存存储了主内存的某些对象的副本,当然线程的工作内存大小是有限制的。当线程操作某个对象时,执行顺序如下: (1) 从主存复制变量到当前工作内存(read and load) (2) 执行代码,改变共享变量值(use and assign) (3) 用工作内存数据刷新主存相关内容(store and write) 当一个共享变量在多个线程的工作内存中都有副本时,如果一个线程修改了这个共享变量, 那么其他线程应该能够看到这个被修改后的值,这就是多线程的可见性问题。 2.有序性 线程在引用变量时不能直接从主内存中引用,如果线程工作内存中没有该变量, 则会从主内存中拷贝一个副本到工作内存中,这个过程为read-load,完成后线程会引用该副本。 当同一线程再度引用该字段时,有可能重新从主存中获取变量副本(read-load-use), 也有可能直接引用原来的副本(use),也就是说read,load,use顺序可以由JVM实现系统决定。 线程不能直接为主存中中字段赋值,它会将值指定给工作内存中的变量副本(assign), 完成后这个变量副本会同步到主存储区(store-write),至于何时同步过去,根据JVM实现系统决定,这就 造成了线程安全问题 java线程安全解决方法 一.使用synchronized synchronized关键字的作用域有二种: 同步加锁的是对象,而不是代码1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法; 2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。五、以上规则对其它对象锁同样适用.参考:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html二。volatile是java提供的一种同步手段,只不过它是轻量级的同步,为什么这么说,因为volatile只能保证多线程的内存可见性,不能保证多线程的执行有序性。而最彻底的同步要保证有序性和可见性,例如synchronized。任何被volatile修饰的变量,都不拷贝副本到工作内存,任何修改都及时写在主存。因此对于Valatile修饰的变量的修改,所有线程马上就能看到,但是volatile不能保证对变量的修改是有序的public volatile int a; 需要满足1)对变量的写操作不依赖于当前值。2)该变量没有包含在具有其他变量的不变式中参考:http://www.2cto.com/kf/201202/118486.html

热点排行