2015年4月—2024年4月,论坛已建立9周年,欢迎加入QQ群讨论:419848937

[JAVA小贴士]为什么要线程安全

主要是游戏中一些经典任务、游戏资料的科普.
回复
头像
hagcse
Mr.GL
Mr.GL
帖子: 151
注册时间: 2018-02-25 15:50

[JAVA小贴士]为什么要线程安全

帖子 hagcse » 2018-03-10 16:05

在大多数情况下,各个线程之间掌握的资源对彼此都是不可视的状态。一个正常的程序也不会频繁的线程之间互相询问状态。而CPU的调度又是随机的,这样就会出现线程安全的问题。
举例:
假设我们现在有一个变量
boolean a = false;
现在有2条线程TA,TB
我们用2条线程对a进行取值,重新赋值,和输出结果。
由于CPU的调度是不确定性的,那么就会出现下面这种情况。
TA先访问a 获取到a当前值为false
随后CPU立刻切换到TB,TB访问了a获取到了false,这个时候CPU没有切换回TA,TB对a进行了修改,将a = true
这个时候TA是不知道a的值已经修改为true了,
然后CPU切换回TA 让他输出a的值,他输出了false,而实际上内存中的a已经为true了
这就是一种常见的线程安全问题。

如果你要保证数据完全准确,就必须考虑线程安全。

线程安全的实现思路非常简单(同步)。
在Java中有一个关键字叫做synchronized,表示线程安全,其原理是对要访问的数据进行加锁,当另外一个线程中途访问此数据时,因为此数据有锁,另外一个线程不会立刻访问,而是暂时等待一下,等原始线程处理结束后,系统会自动释放锁。
这就好比试衣间,一个人进去以后,会挂起锁,另外一个人是不能进去的。
synchronized 属于“重型”锁,使用synchronized后,系统的性能会大幅下降。


synchronized的使用方法举例

这是一个普通方法;
public void addExp(int value)
{
exp+= value;
}



下面是一个同步的方法:
public synchronized void addExp(int value)
{
exp+= value;
}


注意:当系统访问了 addExp方法时,锁定的不是该方法,而是当前访问的对象,所以该对象的其他属性也暂时无法被其他线程访问
图片

回复