Java开发中线程的安全问题以及产生的原因?

Java开发中线程的安全问题以及产生的原因?,第1张

Java如何保证原子性常用的保证Java *** 作原子性的工具是锁和同步方法(或者同步代码块)。使用锁,可以保证同一时间只有一个线程能拿到锁,也就保证了同一时间只有一个线程能执行申请锁和释放锁之间的代码。
与锁类似的是同步方法或者同步代码块。使用非静态同步方法时,锁住的是当前实例;使用静态同步方法时,锁住的是该类的Class对象;使用静态代码块时,锁住的是synchronized关键字后面括号内的对象。

线程不安全的场合很多,比如像 *** 作系统中的用户界面、打印机等外设、控制台输出,都不允许并发(设想两个程序同时要输出文字到同一个屏幕,那还不乱套了)
在代码中,每个线程有自己的堆栈但是共享整个堆,所以访问那些全局的变量,也必须同步,否则会出现脏读数据。
同步也不是万能的良药。不当的锁定会导致程序死锁,而且多线程本身就是为了提高性能,但是同步使用多了,程序又实质上退化成了单线程程序,用多线程的意义也就没了。

javautilconcurrent ConcurrentLinkedQueue 类提供了高效的、可伸缩的、线程安全的非阻塞 FIFO 队列。
自己去参考一下jdk5或6的api文档,里面已经实现了

JAVA中如何保证线程安全以及主键自增有序

一、常见场景

多个线程针对一个i进行主键自增。多线程下如果不做安全策略,将会导致各个现成获取的i值重复,导致脏数据

常见策略

1、增加syschroize进行线程同步

2、使用lock、unlock处理

3、使用reetrantent 锁进行锁定

缺点:容易造成性能低下,或者编写代码容易造成死锁

二、新方案

jdk新提供的功能,atomicInteger(还有其他一atomic开头的原子性 *** 作类)

AtomicInteger,一个提供原子 *** 作的Integer的类。在Java语言中,++i和i++ *** 作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减 *** 作接口。

原理:通过java的CAS compare and swap,简称cas原语进行 *** 作提升性能,这个也号称乐观锁,不阻塞

观锁实际上并不加锁,当计算遇到冲突或者说前后不一致时会重试 直到成功

CAS有3个 *** 作数 内存值V 要跟内存值做比较的值A 和 新值 B

[html] view plain copy

while(true){

if(V == A){

V = B;

return ;

}else{

A = V;

}

}

CAS的 *** 作对象为volatile类型
volatile类型变量是:CPU直接读写变量所在的内存 而不是把变量copy到寄存器 *** 作
这样对变量的 *** 作所有线程都是可见的
这样做的结果是减少了并发时冲突的概率 但不能完全避免


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13330914.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-16
下一篇 2023-07-16

发表评论

登录后才能评论

评论列表(0条)

保存