线程安全面试题 java,Java 面试系列:线程安全之 synchronized 和 ReentrantLock + 面试题...

前面我们介绍了很多关于多线程的内容,在多线程中有一个很重要的课题需要我们攻克,那就是线程安全问题。线程安全问题指的是在多线程中,各线程之间因为同时操作所产生的数据污染或其他非预期的程序运行结果。

线程安全

1)非线程安全事例

比如 A 和 B 同时给 C 转账的问题,假设 C 原本余额有 100 元,A 给 C 转账 100 元,正在转的途中,此时 B 也给 C 转了 100 元,这个时候 A 先给 C 转账成功,余额变成了 200 元,但 B 事先查询 C 的余额是 100 元,转账成功之后也是 200 元。当 A 和 B 都给 C 转账完成之后,余额还是 200 元,而非预期的 300 元,这就是典型的线程安全的问题。

7c279429ff2c

enter image description here

2)非线程安全代码示例

上面的内容没看明白没关系,下面来看非线程安全的具体代码:class ThreadSafeTest {

static int number = 0;

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

Thread thread1 = new Thread(() -> addNumber());

Thread thread2 = new Thread(() -> addNumber());

thread1.start();

thread2.start();

thread1.join();

thread2.join();

System.out.println("number:" + number);

}

public static void addNumber() {

for (int i = 0; i < 10000; i++) {

++number;

}

}

}

以上程序执行结果如下:number:12085

每次执行的结果可能略有差异,不过几乎不会等于(正确的)累计之和 20000。

3)线程安全的解决方案

线程安全的解决方案有以下几个维度:数据不共享,单线程可见,比如 ThreadLocal 就是单线程可见的;

使用线程安全类,比如 StringBuffer 和 JUC(java.util.concurrent)下的安全类(后面文章会专门介绍);

使用同步代码或者锁。

线程同步和锁

1)synchronized

① synchronized 介绍

synchronized 是 Java 提供的同步机制,当一个线程正在操作同步代码块(synchronized 修饰的代码)时,其他线程只能阻塞等待原有线程执行完再执行。

② synchronized 使用

synchronized 可以修饰代码块或者方法,示例代码如下:// 修饰代码块

synchronized (this) {

// do something

}

// 修饰方法

synchronized void method() {

// do something

}

使用 synchronized 完善本文开头的非线程安全的代码。

方法一:使用 synchronized 修饰代码块,代码如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值