摘要:线程安全问题在并发编程学习之基础概念提到,多线程的劣势之一,有个线程安全问题,现在看看下面的例子。那么,该怎么解决呢,很简单,在方法前加个同步锁。运行结果如下有两种情况,是因为看谁先抢占锁,但是输出的算法结果是正确的。
线程安全问题
在java并发编程学习之基础概念提到,多线程的劣势之一,有个线程安全问题,现在看看下面的例子。
public class NotSafeDemo { private int num = 0; public void add(int value) { try { num = num + value; Thread.sleep(100); System.out.println("num:" + num); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { NotSafeDemo synchronizeDemo = new NotSafeDemo(); AddThread1 addThread1 = new AddThread1(synchronizeDemo); AddThread2 addThread2 = new AddThread2(synchronizeDemo); addThread1.start(); addThread2.start(); } } class AddThread1 extends Thread { NotSafeDemo synchronizeDemo; public AddThread1(NotSafeDemo synchronizeDemo) { this.synchronizeDemo = synchronizeDemo; } @Override public void run() { synchronizeDemo.add(1); } } class AddThread2 extends Thread { NotSafeDemo synchronizeDemo; public AddThread2(NotSafeDemo synchronizeDemo) { this.synchronizeDemo = synchronizeDemo; } @Override public void run() { synchronizeDemo.add(2); } }
运行结果如下:
为什么会不安全呢,在java并发编程学习之基础概念提过,两个线程共享一个进程的资源,也就是说,num这个值,是共享的,在还没输出num的时候,已经被第二个线程,改成3,所以两次输出都是3。那么,该怎么解决呢,很简单,在方法前加个同步锁synchronized。
synchronized public void add(int value) { try { int temp = num; num = num + value; Thread.sleep(100); System.out.println(value + "+" + temp + "=" + num); } catch (InterruptedException e) { e.printStackTrace(); } }
运行结果如下:
有两种情况,是因为看谁先抢占锁,但是输出的算法结果是正确的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/75147.html
摘要:不释放持有的锁,释放锁。在调用方法前,必须持有锁,调用唤醒,也要持有锁。休眠一定时间后,进入就绪状态。这两个都能被方法中断当前状态。用法方获取锁判断条件,不满足继续满足执行其他业务方获取锁改变条件通知为什么是而不是会一直循环,直到条件满足。 sleep和wait sleep是Thread类的方法,wait是Object的方法。 sleep可以到处使用,wait必须是在同步方法或者代码...
摘要:线程把的值放在中。线程执行,得到的为。,,独占锁,会导致其他所有需要锁的线程挂起,等待持有锁的线程释放锁。可见性,不保证原子性。乐观锁,不适用锁的情况下实现多线程的变量同步。性能问题在并发量较高的情况下,如果一直不成功,会一直增加的开销。 cas原理 cas全称Compare and swap,比较和交换的意思。原子操作,需要硬件的支持。三个基本操作数:内存地址V,旧的预期值A,要修改...
摘要:的应用方式代码块作用范围在中,作用对象是调用这个代码块的对象。方法进来了出来了运行的结果如下等把方法执行完,释放了的锁,才开始执行。静态方法运行的结果如下等待执行完才执行,说明是类锁类所的另外一种形式运行结果如下 synchronized的应用方式 代码块:作用范围在{}中,作用对象是调用这个代码块的对象。 方法:作用范围是一个方法,作用对象是调用这个方法的对象。 静态方法:作用范围...
摘要:显示锁和内置锁内置锁优势代码简洁不会因为没释放锁,导致锁泄露。显示锁优势灵活性强,锁的获取可以被中断,可以尝试获取锁。接口接口主要方法如下获取锁尝试获取锁,表示未加锁的情况。会进行抢锁操作,如果获取不到锁,也会进入阻塞队列等到唤醒。 显示锁和内置锁 内置锁(Synchronized)优势 代码简洁 不会因为没释放锁,导致锁泄露。 显示锁(Lock)优势 灵活性强,锁的获取可以被中...
摘要:和是配套使用的,方法容易导致死锁。方法不会保证线程的资源正常释放方法给线程打个停止标记,将线程的中断状态设置为,并没有马上强制中断线程,线程是否中断由线程自己决定。终结状态,还是返回。方法判断当前线程是否中断,清除中断标志。 resume、suspend、stop resume和suspend是配套使用的,suspend方法容易导致死锁。 stop方法不会保证线程的资源正常释放 i...
阅读 1271·2021-10-08 10:04
阅读 1855·2021-09-04 16:40
阅读 2517·2019-08-30 13:21
阅读 2254·2019-08-29 15:10
阅读 2815·2019-08-29 12:35
阅读 1164·2019-08-26 17:41
阅读 3045·2019-08-26 17:03
阅读 1109·2019-08-26 12:01