• 对Map进行复合操作(读写)且并发执行时,无法保证业务的行为是正确的,对读写操作进行同步则可以解决。


    ConcurrentHashMap通常只被看做并发效率更高的Map,用来替换其他线程安全的Map容器,比如 HashtableCollections.synchronizedMap线程安全的容器,特别是Map,很多情况下一个业务中 涉及容器的操作有多个(读getput,remove),即复合操作,而在并发执行时,线程安全的容器只能保证自身的数据不被破 坏,和数据在多个线程间是可见的,但无法保证业务的行为是否正确

    以下分别使用HashMap、ConcurrentHashMap、HashTable边遍历时边更新,运行了3个线程,理论上最后得到6000

     知识点了解:

    创建线程有三种方式:1、继承Thread类。2、实现Runnable接口。3、实现Callable接口。

    实现Runnable和实现Callable接口的方式基本相同,不过是后者执行call()方法有返回值,前者线程执行体run()方法无返回值,因此可以把这两种方式归为一种这种方式,与继承Thread类的方法之间的差别如下:

    1、线程只是实现Runnable或实现Callable接口,还可以继承其他类

    2、这种方式下,多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形

    3、但是编程稍微复杂,如果需要访问当前线程,必须调用Thread.currentThread()方法。

    4、继承Thread类的线程类不能再继承其他父类Java单继承决定)。

    注:一般推荐采用实现接口的方式来创建多线程,因为不仅还可以继承其他类,而继承Thread类的线程类不能再继承其他父类,多个线程还可以共享一个target对象,非常适合多线程处理同一份资源的情形。

    运行结果如下:

    1、如果使用HashMap,结果为5136

    2、如果使用ConcurrentHashMap,结果为4684,因为只能保证对容器的操作是没问题的,但是不能保证业务是没有问题的,因为是复和操作且并发执行。

    3、HashTable也不能保证业务没有问题。

    线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写 操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行操作,一般都需要考虑线
    程同步, 否则的话就可能影响线程安全
     

    知识点了解:

    当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题。 要解决上述多线程并发访问一个资源的安全问题,Java中提供了同步机制(synchronized)来解决。

    1、同步代码块

    2、同步方法

     非静态同步方法使用的是 this锁,静态同步方法使用的是当前方法所在类的字节码对象。

    3、Lock锁

     4、volatile变量

    如果非要在这种情况下保证线程安全问题,同步就可以了,加同步代码块,保证读写是同步的

  • 相关阅读:
    Django ajax 实现 loading 效果
    K8S service 简单介绍
    K8S Pod 生命周期 (二)
    异度之刃 Xenoblade 后感
    Nested Prefab Mode 嵌套预制体 保存问题 Dirty
    GIT速成
    Surface电池阈值
    如何删除通知栏无效图标(重置任务栏通知区域)
    Mouse For Winpad
    Re:LieF ~親愛なるあなたへ~ 后感
  • 原文地址:https://www.cnblogs.com/zwh0910/p/14440539.html
Copyright © 2020-2023  润新知