java并发的初步思考 —— 同步实现及比较
来源:互联网 发布:macbook pro 删除软件 编辑:程序博客网 时间:2024/05/16 18:19
并发的现象越来越普遍。特别是在基于B/S架构下,用户群体的随机访问性、数量庞大性。用户的每一次连接都会在服务端的接收容器内创建或者占用一个线程,数量一庞大,资源的消耗及服务的稳定性甚至可用性将成为可考验的问题,使得并发问题越趋突显。
线程运行的环境是进程内,线程由进程创建,其本身并不占有系统资源而只有一点在运行中必不可少的资源(堆栈、当前指令指针、寄存器组合等)。当然,不占用不代表不使用,而这种不占用式的使用就成了名副其实的“共享使用”。共享使用的问题,正是并发中要解决的问题。
并发可以引起什么样的问题呢,可以看看下面这个例子:
public class MultiThread{private int i = 0;private String value = null;public void run(){if(i++%2 == 0){value = "abcdefghijk";for(int i = 0; i < value.length(); i++)System.out.print(value.charAt(i));System.out.println();}else{value = "1234567890";for(int i = 0; i < value.length(); i++)System.out.print(value.charAt(i));System.out.println();}}public static void main(String[] args) {final MultiThread source = new MultiThread();for(int i = 0; i < 4; i++){new Thread(new Runnable(){public void run(){while(true)source.run();}}).start();}}}可以看出,乱序了!这里是启动4个子线程,同时访问同一个资源source。并发的现状使得source中run方法内资源value的不定时改变!value只有一个,但4个人抢中用!
其实,线程的基因里,就决定了它“占有”的资源依然可被共用的特性,即基因决定它是共享的。那么该如何解决这个问题呢?
同步!乱序并发的东西,让它串行起来!同步,应该说是最简单的一种解决方式。同步,在抽象语义上,是指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系。而在线程实际的应用中,就是排队,默认就是FIFO(first in first out)。只要在需要限制的资源上或方法上使用 synchronized 关键字即可。同步的策略,是在程序的层面上实行的。确实可以解决共享性带来的问题,但是,当并发量达到一定程度后,稳定性是有了,可处理的性能却是大大的降低了。
如上代码可以改为synchronized的同步方式:
public synchronized void run(){if(i++%2 == 0){value = "abcdefghijk";for(int i = 0; i < value.length(); i++)System.out.print(value.charAt(i));System.out.println();}else{value = "1234567890";for(int i = 0; i < value.length(); i++)System.out.print(value.charAt(i));System.out.println();}}
现在在Java5中也加入了新的同步锁java.util.concurrent.locks.ReentrantLock,及更有针对性的java.util.concurrent.locks.ReentrantReadWriteLock。java.util.concurrent.locks.ReentrantReadWriteLock顾名思义,就是可以对同步块加ReadLock读锁或者WriteLock写锁,常与try-catch-finally语句块配合使用。
你可能想要比较这两种同步方式孰优孰劣,或者说这两种方式有什么区别。
(1)使用上:
这样说吧,synchronized方式是Java的原生语法层面方式。在源代码编译后,会产生monitorenter及monitorexit字节码指令,然后通过对锁的计数器进行加一减一的操作来实现同步。
而,重入锁ReentrantLock则是Java的API层面的互斥锁。在同步块的两端分别是lock() 及 unlock(),常与try-catch-finally语句块配合使用。它有一些更高级的特性:等待可中断、可实现公平锁、锁可以绑定多个条件。
(1)性能上:
Java5的时候,synchronized方式随线程数的增长,性能急剧下降。而ReentrantLock则能几乎保持在一条水平线上。ReentrantLock性能优秀很多。
Java6之后,性能的擦别就不再那么明显了。为什么?因为synchronized的方式是Java原生语法层面的,JVM更倾向于这方面的性能改进及使用。
参考《深入理解Java虚拟机JVM高级特性与最佳实践 ---- 第五部分:高效并发》
- java并发的初步思考 —— 同步实现及比较
- java并发的初步思考 —— Java线程实现
- Java并发编程实现—Concurrent—初步学习
- iOS 【一篇文章引发的思考 —— 异步/同步/并发/串行】
- java 并发安全的思考
- Java并发框架——同步状态的管理
- java并发编程-1.1线程的创建方法及比较
- Java并发3——同步
- java并发——同步工具类
- Java中不同的并发实现的性能比较
- Java中不同的并发实现的性能比较
- Java中不同的并发实现的性能比较
- Java中不同的并发实现的性能比较
- Java中不同的并发实现的性能比较
- Java 并发及同步相关 Synchronized ReentrantLock
- Java的并发(二) 同步
- 基于ActiveMQ的Topic的数据同步——初步实现
- 并发中的同步--WCF并发体系的同步机制实现
- Required Support Diagnostics for Hanging Databases [ID 452358.1]
- 指针 没看完 需要时再用
- 详解link
- 网页时钟实现代码html5
- 转 win7 vs2010 64位配置opencv2.3.1
- java并发的初步思考 —— 同步实现及比较
- 2012-9-29 大众点评网笔试题
- 正能量:前思科中国区总裁林正刚先生以自己35年职业经历和心得
- poj 2288 (MST) #by nobody
- 把一个godaddy的域名转回国内的注册商
- 常用正则表达式
- 移动互联网应用分类
- 老板看中员工的20个方面 你做到了哪些?
- Javascript面向对象编程:封装