一,什么是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 模式的更多相关文章

  1. 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三

       手把手叫你玩转网络编程系列之三    完毕port(Completion Port)具体解释                                                    ...

  2. Android多线程分析之三:Handler,Looper的实现

    Android多线程分析之三:Handler,Looper的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多 ...

  3. Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

    概要 本章对Java.util.concurrent包中的ConcurrentSkipListMap类进行详细的介绍.内容包括:ConcurrentSkipListMap介绍ConcurrentSki ...

  4. 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 ...

  5. .NET 4 并行(多核)编程系列之三 从Task的取消

    原文:.NET 4 并行(多核)编程系列之三 从Task的取消 .NET 4 并行(多核)编程系列之三 从Task的取消 前言:因为Task是.NET 4并行编程最为核心的一个类,也我们在是在并行编程 ...

  6. java多线程系列(三)---等待通知机制

    等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解 ...

  7. java多线程系列 目录

    Java多线程系列1 线程创建以及状态切换    Java多线程系列2 线程常见方法介绍    Java多线程系列3 synchronized 关键词    Java多线程系列4 线程交互(wait和 ...

  8. Java多线程系列——原子类的实现(CAS算法)

    1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronou ...

  9. Java多线程系列——从菜鸟到入门

    持续更新系列. 参考自Java多线程系列目录(共43篇).<Java并发编程实战>.<实战Java高并发程序设计>.<Java并发编程的艺术>. 基础 Java多线 ...

随机推荐

  1. 基于SurfaceView的可拖动视频控件

    视频播放控件(一) 可拖动,变换SurfaceView public class DragSurfaceView extends SurfaceView implements View.OnTouch ...

  2. LeetCode算法题-Minimum Depth of Binary Tree(Java实现)

    这是悦乐书的第168次更新,第170篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第27题(顺位题号是111).给定二叉树,找到它的最小深度.最小深度是沿从根节点到最近的 ...

  3. Java高级教程02

    目录 1.Java线程 1.1. 多线程和多进程 1.2. 线程的执行过程: 1.3. 创建线程的方法 (1). 方法1:通过run() (2). 方法2: 复写Runnable接口(推荐) 1.4. ...

  4. CISCO 动态路由(RIP)

    RIP(路由信息协议):是一种内部网关协议(IGP),是一种动态路由选择协议,基于距离矢量算法(DistanceVectorAlgorithms),使用“跳数”(即metric)来衡量到达目标地址的路 ...

  5. MySQL初识

    1.MySQL版本 社区版:免费的,功能够用. 商业版:更能更加强大,更加稳定,但是收费的. 2.每个版本都分四个版本发布 Alpha版本:一般只在开发公司内部使用,不对外公开,测试.自我检查版本: ...

  6. Caused by: java.io.FileNotFoundException: velocity.log (No such file or directory)

    Caused by: org.apache.velocity.exception.VelocityException: Error initializing log: Failed to initia ...

  7. ubuntu如何安装 adobe flash player或adobe插件

    方法/步骤 第一步当然是打开终端控制器.有很多方法,这里推荐使用快捷键:ctrl+alt+T.快捷又方便. 然后更新源列表,使用如下命令:sudo apt-get update,后面要输入密码. 下面 ...

  8. JavaScript数组对象详情

    Array 数组概述 Array 类型是 ECMAScript 最常用的类型.javaScript 中的 Array 类型和其他语言中的数组有着很大的区别. 虽然数组都是有序排列,但 javaScri ...

  9. [tool] Visual Studio Code python配置

    语言设置 安装中文插件即可成为中文 选择一个Python解释器 Python是一种解释型语言,为了运行Python代码并获取Python IntelliSense,您必须告诉VS Code使用哪个解释 ...

  10. C# Lambda 表达式学习之(四):动态构建类似于 c => c.Age == 2 || c.Age == 5 || c => c.Age == 17 等等一个或多个 OrElse 的表达式

    可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...