1.什么是线程安全?
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的数据时,进行保护,其它线程不能进行访问直到该线程读取完,其它线程才可以使用.(类似于上厕所关门,其他人不能进去)
2.什么是线程不安全?
线程不安全就是不提供数据访问保护,有可能会出现多个线程先后更改数据,或者没有数据等
例子:
火车站买票,总共有1000张票,有四个窗口在卖,
如果线程安全,每个人买到的票都是从1000-1的,不会存在重复问题,
如果线程不安全,就会出现或许两个人买到的是同一张票(所谓的假数据)
3.线程安全问题出现的原因?
从上面两个回答可知,无论是安全不安全,其围绕的重点也是在线程更改数据和没有办法更改数据.
由此我们知道,线程安全问题都是由全局变量及静态变量引起的。
4.注意:
若每个线程中,对全局变量,静态变量只有读操作,而没有写的操作,一般来说,这个全局变量是线程安全的,若有多个线程同事执行写操作,一般需要考虑线程同步,否则的话就有可能影响线程安全.
线程安全的,改变了数据,只是自己手动改变的,而不是因为线程不安全引起的问题.
5.解决多线程并发访问资源的安全问题,有三种方式:
参考自:
1.同步代码块
2.同步方法
3.锁机制
1. synchronized(同步锁)
{
需要同步操作的代码
}
同步锁:
为了保证每个线程都能正常执行原子操作,Java引入了线程同步机制.也称为同步监听对象/同步锁/ 同步监听器/互斥锁。
实际上,对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁,谁拿到锁,谁就可以进 入代码块,其他线程只能在代码块外面等着,而且注意,在任何时候,最多允许一个线程拥有同 步锁.
Java程序运行可以使用任何对象作为同步监听对象,但是一般的,我们把当前并发访问的共同资源 作为同步监听对象.
以上代码就是一个卖票的同步代码块的方法2.同步方法:
使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着.
Synchronized public void doWork(){
///TODO
}
同步锁是谁:
对于非static方法,同步锁就是this.
对于static方法,我们使用当前方法所在类的字节码对象(Apple2.class).
注意:
不要使用synchronized修饰run方法,修饰之后,某一个线程就执行完了所有的功能.好比是多个线程出现串行.
解决方案:把需要同步操作的代码定义在一个新的方法中,并且该方法使用synchronized修饰,再在run方法中调用该新的方法即可.
实际上,同步代码块和同步方法差不了多少,在本质上是一样的,两者都用了一个关键字synchronized,synchronized保证了多线程并发访问时的同步操作,避免线程的安全性问题,但是有一个弊端,就是使用synchronized的方法/代码块的性能比不用要低一些,因此如果要用synchronized,建议尽量减小synchronized的作用域。
同步方法3.锁机制
注意lock的位置
网友评论