Java 多线程安全问题浅析

我们都知道,当多线程访问共享的资源时,可能会出现线程安全问题。比如:卖电影票、火车票等

问题产生了,那么我们如何解决呢?

解决问题最根本的方法:当一个线程进入数据操作时,无论是否休眠或阻塞,其他的线程只能等待。举个栗子:比如排队上厕所

Java为了解决这个线程安全问题,提供了 同步 的技术 - 同步代码块 和 同步方法。虽然这样程序执行效率降低了,但是为了安全性必须得牺牲效率。语法如下

//同步代码块
synchronized(任意对象){
    线程操作的共享数据的代码块
}

这里的 任意对象 :同步锁/对象监视器

//同步方法:在方法声明上加上 synchronized
public synchronized void pay(){
    ...线程操作的共享数据的代码块
}

同步方法中的对象锁是本类对象引用 this
静态同步方法中的对象锁是 本类的字节码文件 (xxx.class)

同步机制是如何保证安全性的?
没有锁的线程不能执行,只能等。线程遇到同步代码块时,先判断锁,如果有就获取锁,如果没有就等待;如果成功获取到锁才能执行程序,执行完后释放掉锁。
在同步中的线程,不走出同步代码部分,不会释放锁。

Java 在 1.5 版本后,提供了 Lock 接口 替换了 同步代码块,以达到线程的安全性。

Lock接口方法:
lock() 获取锁
unlock() 释放锁
这里我们使用它的实现类:ReentrantLock

Lock接口的使用
1、在成员位置创建Lock子类对象
Lock lock = new ReentrantLock();
2、在线程操作的共享数据块前后添加方法
lock.lock();
try{
    线程操作共享数据的操作
} catch(Exception ex){
    ...
} finally {
    lock.unlock();
}

猜你喜欢

转载自blog.csdn.net/FresherHe/article/details/82690736