专栏首页JVMGCJava线程安全策略
原创

Java线程安全策略

线程安全策略

创建后状态不能被修改的对象叫做不可变对象. 不可变的对象天生就是线程安全的. 不可变对象的常量(变量)是在构造函数中创建的,既然它们的状态永远无法被改变,那么它们永远就是线程安全的。

不可变对象需要满足的条件

  • 对象创建以后其状态就不能修改。
  • 对象的所有域都是fina类型。
  • 对象是正确创建的(在对象创建期间,this引用没有逸出)

并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了

final

final关键字:类,方法,变量。

  • 修饰类

不能被继承,final类中的成员属性可以根据需要设置成final,但是final类中所有的成员方法都被隐式的指定为final,一般不建议将类设置成final.

  • 修饰方法

锁定方法不能被继承类修改

  • 修饰变量

基本数据类型变量,初始化后就不能被修改。引用类型变量,在初始化后就不能指向别的引用。

//线程不安全

package com.rumenz.task.single;

import com.google.common.collect.Maps;
import java.util.Map;

public class ImmutableExample1 {

    private final static Integer a=1;
    private final static Integer b=2;

    //指向的引用不能被修改,但是map里面的值可以修改
    private final static Map<Integer,Integer> map= Maps.newHashMap();


    static {
        map.put(1, 1);
    }

    public static void main(String[] args) {
       //a=10; 编译期报错
       //b=20; 编译期报错
       map.put(2, 2); //线程不安全
    }
}

Collections

java提供Collections工具类,在类中提供了多种不允许修改的方法。

Collections.unmodifiableXXX:Collection、List、Set、Map...

//线程安全
package com.rumenz.task.single;

import com.google.common.collect.Maps;

import java.util.Collections;
import java.util.Map;


public class ImmutableExample1 {

    private final static Integer a=1;
    private final static Integer b=2;

    //指向的引用不能被修改,但是map里面的值可以修改
    private  static Map<Integer,Integer> map= Maps.newHashMap();


    static {
        map.put(1, 1);
        //处理后map是不可以被修改的
        map= Collections.unmodifiableMap(map);
    }

    public static void main(String[] args) {
       //允许操作,但是操作会报错
       map.put(2, 2);
    }
}


Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableMap.put(Collections.java:1457)
	at com.rumenz.task.single.ImmutableExample1.main(ImmutableExample1.java:31)

Collections.unmodifiableMap源码

public class Collections {
    public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
        return new UnmodifiableMap<>(m);
    }
    private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
        @Override
        public boolean remove(Object key, Object value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean replace(K key, V oldValue, V newValue) {
            throw new UnsupportedOperationException();
        }
    }
}

Guava

谷歌的Guava中提供类似Java中的Collections

ImmutableXXX:Collection、List、Set、Map...

<dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
   <version>23.0</version>
</dependency>
//线程安全

public class ImmutableExample3 {

    private final static ImmutableList<Integer> list = ImmutableList.of(1, 2, 3);
    
    private final static List<Integer> lists = ImmutableList.of(1, 2, 3);

    private final static ImmutableSet set = ImmutableSet.copyOf(list);

    private final static ImmutableMap<Integer, Integer> map = ImmutableMap.of(1, 2, 3, 4);

    private final static ImmutableMap<Integer, Integer> map2 = ImmutableMap.<Integer, Integer>builder()
            .put(1, 2).put(3, 4).put(5, 6).build();

    public static void main(String[] args) {
        System.out.println(map2.get(3));
    }
}
wx.jpg

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java线程安全策略总结-0

    newHashMap已经是不可变,不能再添加新元素了。如果再进行put操作,会抛出java.lang.UnsupportedOperationException...

    用户2032165
  • Java线程安全策略与多线程并发最佳实践

    不可变对象(Immutable Objects)是指对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能改变,任何对它的改变都应该产生一个新的对象。

    全菜工程师小辉
  • Java并发编程(4)- 线程安全策略

    有一种对象发布了就是安全的,这就是不可变对象,本小节简单介绍一下不可变对象。不可变对象可以在多线程在保证线程安全,不可变对象需要满足的条件:

    端碗吹水
  • Java并发编程与高并发之线程安全策略

    1、安全的发布对象,有一种对象只要发布了,就是安全的,就是不可变对象。一个类的对象是不可变的对象,不可变对象必须满足三个条件。

    别先生
  • 并发编程-11线程安全策略之线程封闭

    在上篇博文并发编程-10线程安全策略之不可变对象 ,我们通过介绍使用线程安全的不可变对象可以保证线程安全。

    小小工匠
  • 并发编程-12线程安全策略之常见的线程不安全类

    所谓线程不安全的类,是指一个类的实例对象可以同时被多个线程访问,如果不做同步或线程安全的处理,就会表现出线程不安全的行为,比如逻辑处理错误、抛出异常等。

    小小工匠
  • 组策略安全-设备限制安全策略

    组策略(Group Policy)是Microsoft Windows系统管理员为用户和计算机定义并控制程序、网络资源及操作系统行为的主要工具。通过使用组策略可...

    用户7881870
  • 组策略安全-账户策略

    组策略(Group Policy)是Microsoft Windows系统管理员为用户和计算机定义并控制程序、网络资源及操作系统行为的主要工具。通过使用组策略可...

    用户7881870
  • 组策略安全-审核策略

    组策略(Group Policy)是Microsoft Windows系统管理员为用户和计算机定义并控制程序、网络资源及操作系统行为的主要工具。通过使用组策略可...

    用户7881870
  • MySQL安全策略

    数据是企业核心资产,数据对企业而言是最重要的工作之一。稍有不慎,极有可能发生数据无意泄露,甚至被黑客恶意窃取的风险。每年业界都会传出几起大事件,某知名或不知名的...

    用户7657330
  • 浅谈synchronized 和 volatitle 实现线程安全的策略

    对线程安全的理解就是多个线程同时操作一个共享变量时会产生意料之外的情况,这种情况就是线程不安全。注意:只有写操作才可能出现线程不安全,对共享变量只进行读操作线程...

    java乐园
  • 组策略安全-软件限制策略

    软件限制策略是 Microsoft Windows XP 和 Microsoft Windows Server 2003 中的一项新功能。它们提供了一套策略驱动...

    用户7881870
  • 慕课网高并发实战(六)- 线程安全策略

    ThreadLocal 实例保存登录用户信息 (具体的业务场景,和拦截器的使用就不赘述了,大家可以购买课程详细学习)

    Meet相识
  • 并发编程-10线程安全策略之不可变对象

    需要我们注意的是,final修饰引用类型时,虽然不能将引用再指向别的对象,但可修改该对象的值。 线程不安全

    小小工匠
  • 安全策略即代码 | Conjur策略简介

    每个Conjur工作流都以Conjur策略开始:无论是教程、演练、设置脚本、博客发布指引,其中都包含安全策略。这是因为Conjur中的所有内容都存在于安全上下文...

    网络安全观
  • Java线程(一):线程安全与不安全

            作为一个Java web开发人员,很少也不需要去处理线程,因为服务器已经帮我们处理好了。记得大一刚学Java的时候,老师带着我们做了一个局域网聊...

    高爽
  • java 多线程线程安全

    在多线程中使用共享资源,对共享资源的操作不是原子性,就会导致数据不一致的情况 例如 : index ++ 操作 index ++ 实际上相当于 1. ind...

    黑白格
  • [ Security ] WEB安全 ( 三 ) 之 Cookie安全策略

    首先,cookies 是一段字符串,这一段字符串是存储在前端的浏览器中。他的容量很小只有 4k 。由于 HTTP 协议是一个无状态的协议,在进行通信的时候都需要...

    GavinUI
  • PHP代码安全策略

    php如果具有root权限,且在脚本中允许用户删除文件,那么用户提交数据,不进行过滤,就非常有可能删除系统文件

    luxixing

扫码关注云+社区

领取腾讯云代金券