`
臻是二哥
  • 浏览: 188432 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
Group-logo
Java技术分享
浏览量:0
社区版块
存档分类
最新评论

JAVA并发-为现有的线程安全类添加原子方法

阅读更多
JAVA中有许多线程安全的基础模块类,一般情况下,这些基础模块类能满足我们需要的所有操作,但更多时候,他们并不能满足我们所有的需要。此时,我们需要想办法在不破坏已有的线程安全类的基础上添加一个新的原子操作。有如下4中方案:
1 修改类的源码,以添加新的原子操作
2 继承该线程安全类,并添加原子操作
3 使用客户端加锁方式
4 使用组合方式(推荐)
一般来讲,修改源码的方式不太可行,这样会破坏原有类的封装性而且有些时候,源码不可获得。我们从第二种方式开始举例:

假设现在对于类Vector,我们知道它是线程安全类。如果想为他添加一个“若没有则添加”方法,可是如下进行:
public class ImprovedVector<T> extends Vector<T>{
    public synchronized boolean putIfAbsent(T x){
        boolean flag=contains(x);
        if(!flag)
             add(x);
        return !flag;
    }
}

我们来分析上面的代码:使用ImprovedVector类对象的内置锁,保证了contains()和add()方法的原子性,由于ImprovedVector类对象的内置锁也就是Vector类对象的内置锁(即add()方法和contains()方法的锁),这样有保证了add()方法和contains()方法的可见性,可以达到预期效果。

第三种方法举例:
(错误的实现)
public class ImprovedList<T>{
    public List<T> list=Collections.synchronizedList(new ArrayList<T>());
    public synchronized boolean putIfAbsent(T x){
        boolean flag=list.contains(x);
        if(!flag)
             list.add(x);
        return !flag;
    }
}

上面的例子是一个错误的例子,我们来分析下:首先,synchronized保证了list.contains()方法和list.add()方法的原子性,假设现在有一个类对象在执行putIfAbsent()方法,而且即将执行(还没执行)list.add(2)方法,此时,有另外一个线程抢先执行了list.add(2)方法,该线程执行完毕之后,释放了list的锁,接着即将执行(还没执行)list.add(2)方法开始得到CPU并执行。瞧,这个过程中,数字2被添加了2次。就是说,上面的代码中仅仅保证了contains()方法和add()方法的原子性,以及对对list引用操作的互斥性,并没有保证list.add()方法的可见性。
仔细想想,问题出在putIfAbsent()方法的锁与list对象的锁不是同一个,putIfAbsent()方法的锁是ImprovedList类的锁,而list.add()方法的锁是Collections.synchronizedList()使用的锁,因此将上面的代码改成:
(正确的实现)
public class ImprovedList<T>{
    public List<T> list=Collections.synchronizedList(new ArrayList<T>());
    public synchronized boolean putIfAbsent(T x){
            synchronized(list){
            boolean flag=list.contains(x);
            if(!flag)
                 list.add(x);
            return !flag;
        }
    }
}


第四种方法举例:
public class ImprovedList<T> implements List<T>{
    private final List<T> list;
    public ImprovedList(List<T> list){
         this.list=list;
    }
    public synchronized boolean putIfAbsent(T x){
            boolean flag=list.contains(x);
            if(!flag)
                 list.add(x);
            return !flag;
        }
    }
    ...实现List<T>接口中的其他方法
}

乍一看发现,上面的代码在安全性方面好像弱了好多, putIfAbsent(T x)方法中的fianl变量list可能连线程安全类都不是,但是对于上面的代码,我们有个假设(当某个链表对象在传递给ImprovedList的构造函数之后,客户代码再也不会使用这个对象,而是使用与其对应的ImprovedList对象),有了这个假设前提,上面的代码就是线程安全的了。

上面就是JAVA并发编程中,在一个已有的线程安全类的基础上添加同步函数的4个方法。


0
5
分享到:
评论

相关推荐

    JAVA并发编程实践-线程安全-学习笔记

    在Java并发编程中,线程安全是一个至关重要的概念,它涉及到多线程环境下对共享数据的正确管理和访问。线程安全意味着当多个线程同时访问一个对象或数据时,对象的状态能够保持一致性和完整性,不会因为并发导致数据...

    Java并发编程-线程安全与基础构建模块

    本文将深入探讨"Java并发编程-线程安全与基础构建模块"这一主题,旨在帮助开发者理解如何有效地处理并发问题,提高程序性能和稳定性。 首先,线程安全是并发编程中的核心概念,指的是多个线程访问同一资源时,无论...

    java 多线程并发实例

    Java的BlockingQueue接口(如ArrayBlockingQueue)非常适合实现这一模型,它提供了线程安全的数据插入和移除操作。 在实例中提到的"全部开始 全部停止 单个停止"可能涉及到线程的启动和控制,这可以通过控制线程的...

    Java 多线程与并发(8-26)-JUC原子类- CAS, Unsafe和原子类详解.pdf

    Java多线程与并发处理是Java编程中的高级话题,涉及到JUC(java.util.concurrent)包中的原子类、CAS(Compare-And-Swap)机制、Unsafe类以及多线程并发的无锁方案和线程安全的实现方法。 CAS是一种无锁的同步机制...

    java并发编程2

    Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。以下是对标题和描述中所提及的几个知识点的详细解释: 1. **线程与并发** - **线程*...

    Java 多线程与并发-Java并发知识体系详解.pdf

    Java并发工具包J.U.C(Java Util Concurrency)包含了丰富的一系列并发组件,如Lock框架(ReentrantLock等)、并发集合(ConcurrentHashMap等)、原子类(AtomicInteger等)、线程池(ExecutorService)和工具类。...

    人工智能-项目实践-多线程-Java多线程高并发实例.zip

    在本项目实践中,我们将深入探讨Java中的多线程与高并发技术,特别是在人工智能领域的应用。Java作为一种广泛应用的编程...通过对这些实例的学习和实践,你将能够更好地驾驭Java并发编程,为你的职业生涯增添更多亮点。

    Java-JUC-多线程 进阶

    Java-JUC-多线程进阶resources是 Java 并发编程的高级课程,涵盖了 Java 中的并发编程概念、线程安全、锁机制、集合类、线程池、函数式接口、Stream流式计算等多个方面。 什么是JUC JUC(Java Utilities for ...

    JAVA并发编程艺术pdf版

    《JAVA并发编程艺术》是Java开发者深入理解和掌握并发编程的一本重要著作,它涵盖了Java并发领域的核心概念和技术。这本书详细阐述了如何在多线程环境下有效地编写高效、可靠的代码,对于提升Java程序员的技能水平...

    java并发编程实践pdf笔记

    - **线程安全** 指在多线程环境下,一个类或方法的行为在任何时候都是可预测的,不会因其他线程的活动而受到影响。 - **非线程安全** 反之,如果在多线程环境下,不保证其行为的正确性,那么就需要采取措施确保...

    Java并发编程实战-高清完整版-带书签

    书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高...

    java多线程中的原子操作

    总结来说,Java多线程中的原子操作是保证并发安全的重要手段,通过使用`java.util.concurrent.atomic`包中的原子类,开发者可以编写出高效且线程安全的代码。同时,自定义的数据结构和工具类如CircularSet和...

    Java 并发编程实战.pdf

    - **并发集合**:如ConcurrentHashMap、CopyOnWriteArrayList等,这些集合类针对多线程环境进行了优化,能够在保证线程安全的同时提高性能。 - **线程通信**:包括线程间的同步、等待、通知等机制,是实现复杂并发...

    Java并发学习-AtomicIntegerFieldUpdater字段原子更新类.docx

    Java并发编程中,AtomicIntegerFieldUpdater 是一个非常重要的工具类,它是Java并发包(concurrent.atomic)下的一个原子更新器,主要用于确保对某个实例对象中的int类型字段进行原子操作。这个类的设计目的是在不改变...

    Java并发-Synchronized关键字.docx

    因此,Java并发库中提供了其他高级并发控制工具,如`java.util.concurrent`包下的`ReentrantLock`、`Semaphore`等,它们在某些场景下可以提供更好的性能和更细粒度的锁控制。 总的来说,`synchronized`关键字是Java...

    黑马程序员_张孝祥_Java多线程与并发库 视频+代码+资料

    3. **原子类**:原子类是Java并发库中提供的一种高效的线程安全类,它们可以实现无需同步的原子更新操作。 - `AtomicInteger`:用于整型变量的原子操作。 - `AtomicLong`:用于长整型变量的原子操作。 - `...

    经典Java --线程

    Java线程是多任务编程的重要概念,它允许程序同时执行多个独立的任务,从而提升程序的效率和响应性。在Java中,线程可以分为两类:用户线程...在实际开发中,应根据需求选择合适的方式和策略,确保线程安全和程序性能。

    java并发编程实战源码,java并发编程实战pdf,Java

    《Java并发编程实战》是Java并发编程领域的一本经典著作,它深入浅出地介绍了如何在Java平台上进行高效的多线程编程。这本书的源码提供了丰富的示例,可以帮助读者更好地理解书中的理论知识并将其应用到实际项目中。...

Global site tag (gtag.js) - Google Analytics