多线程系列之三:Immutable 模式
一,什么是Immutable模式?
immutable就是不变的,不发生改变的。Immutable模式中存在着确保实例状态不发生变化改变的类。这些实例不需要互斥处理。
String就是一个Immutable类,String实例所表示的字符串的内容不会变化。
二,定义一个使用Immutable模式的类
public final class Person {
private final String name;
private final String address;
public Person(String name,String address){
this.name = name;
this.address = address;
}
public String getName(){
return name;
}
public String getAddress(){
return address;
}
@Override
public String toString() {
return "[ Person : name = "+name+",address = "+address+"]";
}
}
final修饰类,无法创建子类,防止子类修改其子段值
private修饰字段,内部可见,防止子类修改字段值
final修饰了字段,赋值后不在改变
三,何时使用这种模式?
1.实例创建后,状态不再发生变化
2.实例是共享的,且被频繁访问时
四,集合类与多线程
1.ArrayList类用于提供可调整大小的数组,是非线程安全的。当多个线程并发执行读写时,是不安全的。
public class WriterThread extends Thread {
private final List<Integer> list;
public WriterThread(List<Integer> list){
super("WriterThread");
this.list = list;
}
@Override
public void run() {
for (int i = 0;true ; i++) {
list.add(i);
list.remove(0);
}
}
}
public class ReaderThread extends Thread{
private final List<Integer> list;
public ReaderThread(List<Integer> list){
super("ReaderThread");
this.list = list;
}
@Override
public void run() {
while (true){
for (int n :list){
System.out.println(n);
}
System.out.println("------");
}
}
}
/**
* 并发读写List,会出异常
* Exception in thread "ReaderThread" java.util.NoSuchElementException
* Exception in thread "ReaderThread" java.util.ConcurrentModificationException
*
*/
public class ListTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();new WriterThread(list).start();
new ReaderThread(list).start();
}
}
2.利用Collections.synchronizedList方法锁进行的同步
利用Collections.synchronizedList方法进行同步,就能够得到线程安全的实例
public class WriterThread extends Thread {
private final List<Integer> list;
public WriterThread(List<Integer> list){
super("WriterThread");
this.list = list;
}
@Override
public void run() {
for (int i = 0;true ; i++) {
list.add(i);
list.remove(0);
}
}
}
public class ReaderThread extends Thread{
private final List<Integer> list;
public ReaderThread(List<Integer> list){
super("ReaderThread");
this.list = list;
}
@Override
public void run() {
while (true){
//使用了synchronizedList,读数据时必须加锁
synchronized (list){
for (int n :list){
System.out.println(n);
}
}
System.out.println("------");
}
}
}
public class ListTest {
public static void main(String[] args) {
List<Integer> arrayList = new ArrayList<>();
List<Integer> list= Collections.synchronizedList(arrayList);
new WriterThread(list).start();
new ReaderThread(list).start();
}
}
3.使用copy-on-write 的java.util.concurrent.CopyOnWriteArrayList类
copy-on-write,就是写时复制,如果使用copy-on-write,当对集合执行 写操作时,内部已确保安全的数组就会被整体复制。复制之后,就无需在使用迭代器依次读取数据时
担心元素被修改了。所以该类不会抛出并发修改异常
public class WriterThread extends Thread {
private final List<Integer> list;
public WriterThread(List<Integer> list){
super("WriterThread");
this.list = list;
}
@Override
public void run() {
for (int i = 0;true ; i++) {
list.add(i);
list.remove(0);
}
}
}
public class ReaderThread extends Thread{
private final List<Integer> list;
public ReaderThread(List<Integer> list){
super("ReaderThread");
this.list = list;
}
@Override
public void run() {
while (true){
for (int n :list){
System.out.println(n);
}
System.out.println("------");
}
}
}
public class CopyOnWriteListTest {
public static void main(String[] args) {
final List<Integer> list = new CopyOnWriteArrayList<>();
new WriterThread(list).start();
new ReaderThread(list).start();
}
}
使用copy-on-write时,每次执行 写操作时都会执行复制。因此程序频繁执行写操作时,如果使用CopyOnWriteArrayList,会比较花费时间。
如果写操作比较少,读炒作频繁时,很适合用CopyOnWriteArrayList。
具体根据情况而定。
多线程系列之三:Immutable 模式的更多相关文章
- 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三
手把手叫你玩转网络编程系列之三 完毕port(Completion Port)具体解释 ...
- Android多线程分析之三:Handler,Looper的实现
Android多线程分析之三:Handler,Looper的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多 ...
- Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
概要 本章对Java.util.concurrent包中的ConcurrentSkipListMap类进行详细的介绍.内容包括:ConcurrentSkipListMap介绍ConcurrentSki ...
- Red Gate系列之三 SQL Server 开发利器 SQL Prompt 5.3.4.1 Edition T-SQL智能感知分析器 完全破解+使用教程
原文:Red Gate系列之三 SQL Server 开发利器 SQL Prompt 5.3.4.1 Edition T-SQL智能感知分析器 完全破解+使用教程 Red Gate系列之三 SQL S ...
- .NET 4 并行(多核)编程系列之三 从Task的取消
原文:.NET 4 并行(多核)编程系列之三 从Task的取消 .NET 4 并行(多核)编程系列之三 从Task的取消 前言:因为Task是.NET 4并行编程最为核心的一个类,也我们在是在并行编程 ...
- java多线程系列(三)---等待通知机制
等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解 ...
- java多线程系列 目录
Java多线程系列1 线程创建以及状态切换 Java多线程系列2 线程常见方法介绍 Java多线程系列3 synchronized 关键词 Java多线程系列4 线程交互(wait和 ...
- Java多线程系列——原子类的实现(CAS算法)
1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronou ...
- Java多线程系列——从菜鸟到入门
持续更新系列. 参考自Java多线程系列目录(共43篇).<Java并发编程实战>.<实战Java高并发程序设计>.<Java并发编程的艺术>. 基础 Java多线 ...
随机推荐
- DubboAdmin部署
1.软件下载 部署管理后台和监控中心需要以下软件 opensesame 下载地址:https://github.com/alibaba/opensesame Dubbo源码下载 https://g ...
- MySQL注入与防御
1.简介 1.1.含义 在一个应用中,数据的安全无疑是最重要的.数据的最终归宿都是数据库,因此如何保证数据库不被恶意攻击者入侵是一项重要且严肃的问题! SQL注入作为一种很流行的攻击手段,一直以来都受 ...
- LeetCode算法题-Ransom Note(Java实现)
这是悦乐书的第212次更新,第225篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第80题(顺位题号是383).给定一个任意赎金票据字符串和另一个包含所有杂志字母的字符串 ...
- Windows10反安装报错error code 2502 2503
先找系统TEMP目录,一般为C:\windows\temp,打开这个目录的权限,为这个目录中的User用户添加权限为完全控制,现在再反安装就不会报错了. 注:原因就是因为系统运行时需要用到临时文件的目 ...
- Zookeeper运维小结--CancelledKeyException
https://www.jianshu.com/p/73eec030db86 项目中用到storm+kafka+zookeeper,在实际应用中zk和kafka常出问题,这里记录下在使用zk过程中的问 ...
- mongoDB python 操作
mongoDB python 操作 import pymongo mongo_client = pymongo.MongoClient(host="127.0.0.1",port= ...
- 设计模式のStatePattern(状态模式)----行为模式
一.产生背景 在面向对象软件设计时,常常碰到某一个对象由于状态的不同而有不同的行为.如果用if else或是switch case等方法处理,对象操作及对象的状态就耦合在一起,碰到复杂的情况就会造成代 ...
- centos7下安装docker(23.docker-swarm之如何访问service)
如何访问service呢? 为了便于分析,我们重新部署web-server 1.删除service 执行命令docker service rm web-server docker service rm ...
- centos7修改系统语言为简体中文
centos7修改系统语言为简体中文 说明 自己装系统时一般都可以自定义选择系统语言.可是云端服务器一般都是安装好的镜像,默认系统语言为英文,对于初学者可能还会有搞不懂的计算机词汇.这里简单说一下ce ...
- svn 锁的处理
svn 锁的处理: 问题: 1:当用户在work copy1 中把某个文件或者文件夹锁住后,删除了这个工作区,重新取下来work copy2,再操作该文件的时候就报错说,该文件已经被锁住,必须先解锁, ...