什么是线程安全的类?

线程安全是指在多线程的运行环境之下,通过一定的同步机制,保证多个线程对同一共享资源的操作能够得到正确的执行,符合这样条件的类称为线程安全的类

如下代码:

public class Main {

    private static int count = 0;

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

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    count++;
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    count++;
                }
            }
        });
        t1.start();t2.start();
        t1.join();t2.join();
        System.out.println(count);
    }

}

两个线程同时操作同一个数据,都累加1000次,结果应该为2000,但事实上并非如此
在这里插入图片描述
虽然count++只是一条语句,但是翻译成机器码之后就编程了多条指令,在串行条件下,我们来分析下累加的过程:
1 读取count的值
2 count值加1
3 将新的值写回内存
在多线程的环境下,两个线程间的代码执行顺序是不明确的,很可能出现如下情况
1 线程A读取count的值为1
2 线程B读取count的值为1
3 线程Acount值+1
4 线程Bcount值+1
5 线程A写回内存,count为1
6 线程B写回内存,count为1

其实一开始,i++只是一条语句,如果不是在底层变成了多个命令,自然也就不会发生这么莫名其妙的问题,这就是操作的原子性,我们把对共享资源的操作想象成一组指令,只要能保证在这组操作执行结束之前其他线程不能操作该资源,那问题就可以得到解决,这就是同步,

public class Main {

    private static int count = 0;

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

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    add();
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    add();
                }
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(count);
    }

    public static synchronized void add() {
        count++;
    }

}

synchronized是java提供的同步机制,可以保存在synchronized修饰的代码未执行结束之前,保证其他线程无法执行count++操作,这样就使得count++的操作具备原子性。但是,这会导致并行的性能降低。

特别说明

无论你写的类是否线程安全,你都无法阻止别人使用该类的方式,在进行java Web开发的时候,虽然你写的类没有考虑线程安全的问题,但服务器会使用多线程去访问同一段代码,这是应对多用户的需要。所以,保证自己的类是线程安全的,如果不是,则需要进行特殊说明。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值