设计线程安全的类

步骤:

找出构成对象状态的所有变量

找出约束状态变量的不变性条件

建立对象状态的并发访问策略

1.在现有的线程安全类中添加功能

(1)重用能减低工作量和提高正确性

(2)如果底层的类改变了同步策略,使用不同的锁来保护它的状态,则子类会被破坏

class BetterVector<E> extends Vector<E>{
    public  synchronized boolean putIfAbsent(E e){
        boolean absent = !contains(e);
        if(absent){
            add(e);
        }
        return absent;
    }
}

2.客户端加锁机制

(1)对于使用对象X的客户端,如果知道X使用的是什么锁,则使用X本身用于保护其状态的锁,来保护这段客户端代码

(2)同样会破坏同步策略的封装

A.错误示例:

class ListHelper<E>{
    public List<E> list = Collections.synchronizedList(new ArrayList<E>());

    public synchronized boolean putIfAbsent(E e){
        boolean absent = !list.contains(e);
        if(absent){
            list.add(e);
        }
        return absent;
    }
}

B.正确示例:

class ListHelper<E>{
    public List<E> list = Collections.synchronizedList(new ArrayList<E>());

    public  boolean putIfAbsent(E e){
        synchronized(list){
            boolean absent = !list.contains(e);
            if(absent){
                list.add(e);
            }
            return absent;
        }
    }
}

3.组合:推荐方式

class ImprovedList<E> implements List<E>{
    private final List<E> list;
    public ImprovedList(List<E> list){
        this.list = list;
    }

    public synchronized boolean putIfAbsent(E e){
            boolean absent = !list.contains(e);
            if(absent){
                list.add(e);
            }
            return absent;
       }

    public synchronized  boolean add(E e) {
        //委托.....

    }
}
时间: 09-20

设计线程安全的类的相关文章

Java 并发编程(三)设计线程安全的类-实例封闭

到目前为止,我们已经介绍了关于线程安全与同步的一些基础知识.然而,我们并不希望对每一次内存访问都进行分析以确保是线程安全的,而是希望将一些现有的线程安全组件组合为更大规模的组合为更大规模的组件或程序.之后,我们会讲一些设计线程安全类的一些基本概念,介绍一些组合模式. 一.设计线程安全的类 在设计线程安全类的过程中,需要包含以下三个基本要素: 1.找出构成对象状态的所有变量 2.找出约束状态变量的不变性条件 3.建立对象状态的并发访问管理策略 要分析对象的状态,首先从对象的域开始.如果对象中所有的

Java线程池工具类

使用线程池的好处: 重用线程,线程的创建和销毁是很耗时的. 控制线程的数量. 线程池工具类: ThreadPool.java package com.zws.thread.pool; import java.util.concurrent.Callable; import java.util.concurrent.Future; /**  *   * @author wensh.zhu  *  */ public interface ThreadPool { void execute(Runna

Java多线程——线程阻塞工具类LockSupport

简述 LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞. 和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执行的情况. 和 Object.wait()相比,它不需要先获得某个对象的锁,也不会抛出 InterruptedException 异常. LockSupport 的静态方法 park()可以阻塞当前线程,类似的还有 parkNanos().parkUntil()等方法.它们实现了一个限时等待,如下图

深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/details/26744661),看代码和提问.讨论都更方便. Java中final的作用主要表如今三方面:修饰变量.修饰方法和修饰类.以下就从这两个方面来解说final的作用.在文末从final及类的设计安全性出发,论述了Java中String为何要被设计成不可变类. 1.final修饰变量 fina

设计一个串口装饰类(1)

团队正在开发一个仪器控制软件的框架,希望该框架能兼容/容忍一些硬件的变换,以及灵活定制建立在该硬件平台之上的工作流.目标仪器使用了很多的串口通信(Serial Port),所以大家觉得应该设计/封装一个统一的串口类来管理串口通信的一致性.就我个人的意见来说,我不是建议在System.IO.Port.SerialPort上再做封装的.串口通信逻辑很简单,基本就是I/O.该类已经提供了同步阻塞模型.基于事件的异步模型,各种I/O快捷方法,所以不认为封装该类可以获得什么更多好处.但是面对框架的 一些其

组件接口(API)设计指南[2]-类接口(class interface)

*返回文件夹阅读其它章节: http://blog.csdn.net/cuibo1123/article/details/39894477 类接口(class interface) 你能够參考MGTileMenu的接口文件. 我们之前谈论了一些接口的细节,这里,例举几个通用规则: 规则1:使用当前平台的描写叙述用语或构架 一个最常见的API错误设计是使用外来的规则,API属于一个特定的平台和相关开发人员生态系统. 你不能使用不论什么其它不同平台的描写叙述用语或构架,这会污染你当前的代码库,并破坏

线程阻塞工具类:LockSupport(读书笔记)

他可以在线程任意位置让线程阻塞, LockSupport的静态方法park()可以阻塞当前线程,类似的还有parkNanos() ParkUntil()等,他们实现了一个限时等待 public class LockSupportDemo { public static Object u = new Object(); static ChangeObjectThread t1 = new ChangeObjectThread("t1"); static ChangeObjectThrea

rocketmq的线程服务基类

RocketMQ有很多的线程服务,这些服务都继承自抽象类ServiceThread. 这个抽象类可以单独抽出来用到我们其他的项目中来,仅仅需要修改下日志模块: /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional

JDK5新特性之线程同步工具类(三)

一. Semaphore实现信号灯 Semaphore可以控制同时访问资源的线程个数, 例如: 实现一个文件允许的并发访问数. Semaphore实现的功能就类似厕所有5个坑, 加入有十个人要上厕所, 那么同时只能有5个人能够占用, 当5个人中的任何一个人离开后, 其中在等待的另外5个人中就有一个可以占用了. 另外等待的5个人中可以是随机获得优先机会, 也可以使按照先来后到的顺序获得机会, 这取决于构造Semaphore对象时传入的参数选项. /** * Semaphore:信号灯 */ pub