线程安全,synchronized与ThreadLocal的区别

本文介绍了线程不安全的概念,即多线程访问共享资源导致的脏读现象,并讨论了线程安全的定义。文章通过实例说明了线程不安全问题,然后介绍了三种保证线程安全的手段:synchronized关键字、ReentrantLock和ThreadLocal。对于ThreadLocal,文章详细讲解了其主要方法、赋值策略以及使用注意事项,包括内存消耗和内存泄漏问题。
摘要由CSDN通过智能技术生成

什么是线程不安全

简单来说就是多线程访问同一个资源,前面的线程修改了资源,但是后面的线程拿到的依旧是以前的资源,造成的一种脏读现象。比如说抢车票,线程A先去查询有1张,同时线程B也去查询也是1张,此时线程A把票取走了,此时已经没有车票了,但是线程B查询出来的还是有一张车票,但是却取不出来。这样的是线程不安全,也就是多线程访问共享资源存在竞争关系,并且有写操作

什么是线程安全

如果代码在多线程状态下运行出来的结果跟单线程运行出来的结果是一样的,就可以说是线程安全的。线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

线程不安全实例

	static int i = 0;

    public static void main(String[] args) throws InterruptedException {


        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                add();
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                add();
            }
        });
        thread1.start();
        thread2.start();

        Thread.sleep(100);
        num();
    }

    public static void add(){
        for (int j = 0;j<100;j++){
            i++;
        }
    }

    public static void num(){
        System.out.println(i);
    }

在这里插入图片描述

如何保证线程安全

1.synchronized关键字

  • 作用于方法上,将方法锁住
    • 静态方法:锁住的是类
    • 非静态方法:锁住的是对象实例,不同实例访问没有影响
  • 锁住代码块
  • 因为锁住的地方只能单个单个线程的执行所有性能会比较低

2.ReentrantLock锁对象

3.ThreadLocal

它是将访问的资源拷贝一份到线程内部,每次进行操作都是对自己线程内部的资源进行操作,并不会影响共享的资源。我个人理解就相当于线程的局部变量,每个线程的局部变量都是互不影响的,在一开始就把共享资源赋值给局部变量,以后每次都对局部变量进行操作,需要注意每次操作完成,记得调用remove方法,不然容易引起内存泄漏。

3.1 主要方法
  • get():得到当前线程局部变量中的值
  • set():在当前线程的局部变量中设置指定的值
  • remove():删除此线程局部变量的当前线程的值
3.2 赋值多个值
  • 一个ThreadLocal只能赋值一个局部变量,如果想要将多个值设置为局部变量需要创建多个ThreadLocal,或者将需要设置的多个值封装成一个对象,进行设置。
3.3 注意事项
  • 由于ThreadLocal是创建线程局部变量来控制线程安全的,所有会对内存产生很大的消耗
  • 使用完ThreadLocal需要及时remove掉局部变量,不然容易引起内存泄漏,进而导致内存溢出

使用ThreadLocal在子线程中无法获取变量

InheritableThreadLocal:可以在子线程获取父线程中设置的局部变量,用法跟ThreadLocal一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值