JAVA并发的性能调整
1.互斥技术
- synchronized
- Lock
- Atomic
性能比较Atomic > Lock > synchronized,当然这不是绝对的。当线程数比较少时,synchronized的效率还是很可观的,并且用这个关键修饰的代码块阅读性很强。所以我们在编程时首先考虑到使用synchronized,当对并发的性能要求高的时候,才考虑使用Lock或者Atomic。Atomic适合简答的对象,如果对象多于复杂,不建议使用。
2.免锁容器
- CopyOnWriteArrayList
- CopyOnWriteArraySet
- concurrentHashMap
- ConcurrentLinkedQueue
在介绍勉锁容器时,先了解一下cow(copy on write)技术。该技术使用的对象一般是类似于数组这样存储量比较大的数据格式。在使用cow技术对数组进行写操作的时候,首先会对原始数组进行建立一个副本,然后对这个副本进行写操作。等到写操作完成后,通过一个原子操作将引用指向这个修改后的副本。这个写操作时互斥的,所以在某一时间段内只有一个线程对数组进行写操作。
在容器中引入cow技术后就是所谓的免锁容器,如CopyOnWriteArrayList。在免锁容器中,对数据的读和写操作可以同时发生,减少了获取锁和释放锁的操作。不过有一点需要注意,读到的始终是原数据的值。
免锁容器一般使用的场景是数据量比较少,读次数多,写次数少。
3.ReadWriteLock
该锁是针对写操作少,读操作多的情况使用。多个读者进行读操作时,不会产生冲突。当读锁被持有时,写操作不能进行。当写锁被其它任务持有时,任何读者都不能进行读操作,直到写锁被释放。
package com.dy.xidian; import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReaderWriterList<T> {
private ArrayList<T> lockedList;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
public ReaderWriterList(int size, T initialValue) {
lockedList = new ArrayList<T>(Collections.nCopies(size, initialValue));
} public T set(int index, T element) {
Lock wlock = lock.writeLock();
wlock.lock();
try {
return lockedList.set(index, element);
} finally {
wlock.unlock();
}
} public T get(int index) {
Lock rlock = lock.readLock();
rlock.lock();
try {
if (lock.getReadLockCount() > 1)
System.out.println(lock.getReadLockCount());
return lockedList.get(index);
} finally {
lock.readLock().unlock();
}
} public static void main(String[] args) {
new ReaderWriterListTest(30, 1);
}
} class ReaderWriterListTest {
ExecutorService exec = Executors.newCachedThreadPool();
private final static int SIZE = 100;
private static Random rand = new Random(47);
private ReaderWriterList<Integer> list = new ReaderWriterList<Integer>(
SIZE, 0); private class Writer implements Runnable { @Override
public void run() {
try {
for (int i = 0; i < 20; i++) {
list.set(i, rand.nextInt());
TimeUnit.MILLISECONDS.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("interrupted!");
}
System.out.println("Writer finished, shutting down");
}
} private class Reader implements Runnable { @Override
public void run() {
try {
while (!Thread.interrupted()) {
for (int i = 0; i < SIZE; i++) {
list.get(i);
TimeUnit.MILLISECONDS.sleep(1);
}
}
} catch (InterruptedException e) {
System.out.println("Read interrupted");
}
}
} public ReaderWriterListTest(int readers, int writers) {
for (int i = 0; i < readers; i++)
exec.execute(new Reader());
for (int i = 0; i < writers; i++)
exec.execute(new Writer());
}
}
JAVA并发的性能调整的更多相关文章
- Tomcat性能调整完整教程
Tomcat性能调整完整教程 发表于:2007-07-13来源:作者:点击数:526 标签: 一. 引言 性能测试与分析是软件 开发 过程中介于架构和调整的一个广泛并比较不容易理解的领域,更是一项较为 ...
- 百万并发中间件系统的内核设计看Java并发性能优化
“ 这篇文章,给大家聊聊一个百万级并发的中间件系统的内核代码里的锁性能优化. 很多同学都对Java并发编程很感兴趣,学习了很多相关的技术和知识.比如volatile.Atomic.synchroniz ...
- 《Java并发编程实战》第十一章 性能与可伸缩性 读书笔记
造成开销的操作包含: 1. 线程之间的协调(比如:锁.触发信号以及内存同步等) 2. 添加�的上下文切换 3. 线程的创建和销毁 4. 线程的调度 一.对性能的思考 1 性能与可伸缩性 执行速度涉及下 ...
- 15套java架构师、集群、高可用、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战视频教程
* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩展. ...
- 15套java架构师、集群、高可用、高可扩 展、高性能、高并发、性能优化Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战视频教程
* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展 ...
- java并发基础(六)--- 活跃性、性能与可伸缩性
<java并发编程实战>的第9章主要介绍GUI编程,在实际开发中实在很少见到,所以这一章的笔记暂时先放一放,从第10章开始到第12章是第三部分,也就是活跃性.性能.与测试,这部分的知识偏理 ...
- 【Java并发基础】安全性、活跃性与性能问题
前言 Java的多线程是一把双刃剑,使用好它可以使我们的程序更高效,但是出现并发问题时,我们的程序将会变得非常糟糕.并发编程中需要注意三方面的问题,分别是安全性.活跃性和性能问题. 安全性问题 我们经 ...
- Java开发代码性能优化总结
代码优化,可能说起来一些人觉得没用.可是我觉得应该平时开发过程中,就尽量要求自己,养成良好习惯,一个个小的优化点,积攒起来绝对是有大幅度效率提升的.好了,将平时看到用到总结的分享给大家. 代码优化的目 ...
- Java并发集合的实现原理
本文简要介绍Java并发编程方面常用的类和集合,并介绍下其实现原理. AtomicInteger 可以用原子方式更新int值.类 AtomicBoolean.AtomicInteger.AtomicL ...
随机推荐
- uniq
-c, --count 在每行前加上表示相应行目出现次数的前缀编号-d, --repeated 只输出重复的行-D, --all-repeated[=delimit-method 显示所有重复的行de ...
- EM basics- the Maxwell Equations
All the two important problems that the EM theory trys to describe and explain are propogation and r ...
- MIT jos 6.828 Fall 2014 训练记录(lab 5)
源代码参见我的github: https://github.com/YaoZengzeng/jos File system perliminaries 我们开发的是一个单用户的操作系统,只提供了足够的 ...
- 迭代加深搜索 codevs 2541 幂运算
codevs 2541 幂运算 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 从m开始,我们只需要6次运算就可以计算出 ...
- Fisker大师用ZBrush制作兽人萨尔全过程
十二年前,暴雪推出第一款网络游戏<魔兽世界>,以迅雷不及掩耳盗铃之势风靡全球:十二年后,魔兽终于改编成大电影,同样掀起了一场巨大的风暴, 接二连三打破了多项票房纪录.纵观游戏史,很难找出一 ...
- Java虚拟机详解02----JVM内存结构
主要内容如下: JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程: JVM启动时,是由java命令/javaw命令来启动的. 二.JVM基本结构: JVM基本结构图: ...
- AC日记——过河卒 洛谷 1002
题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. ...
- Javascript中的对象和原型(3)
在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型 ...
- smarty模板继承
- 运维工作中sed常规操作命令梳理
sed是一个流编辑器(stream editor),一个非交互式的行编辑器.它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间",接着用sed命令处理缓冲 ...