线程的同步机制
- 在多线程编程时有些敏感数据不允许多线程同时访问,此时就要使用一个同步访问技术,就是在同一时刻要保证只有一个线程访问那一个数据,保证数据完成性。
- 也可以理解为,当一个线程在操作数据的时候其他线程是不能操作只能等待,只能等该线程完成操作,其他线程才可以操作这个数据。
举例说明:
/**
* @author admin
* @version 1.0
* Created by on 2023/4/18 13:00
* 有2个用户分别从同一个账户取钱(总额度:10000)
* 每次都是取出1000,当月不足时,就不能取款
* 不能出现超取现象,线程同步问题
*
* 如果这里没有使用synchronized锁机制则会出现超取现象
* 注意这里如果要是用线程sleep 方法必须写在 synchronized 方法块外面 否则会出现只有一个线程在取钱操作
*/
public class HomeWork02 {
public static void main(String[] args){
T t = new T();
Thread A = new Thread(t);
A.setName("线程一");
Thread B = new Thread(t);
B.setName("线程二");
A.start();
B.start();
}
}
/**
* 编写取款线程
* 为什么使用Runnable 因为这类有线程共享问题所以使用Runnable
*/
class T implements Runnable {
/**
* 定义共享变量
*/
private int money = 10000;
Object object = new Object();
@Override
public void run(){
while (true) {
/**
* 使用 synchronized 实现线程同步
* 当一个线程拿到这个this(对象)锁那么执行 synchronized代码块,执行完之后释放this(对象)锁
* 拿不到 this(对象锁) 就等待blocked
* 请况一:可能会出现 A 拿到锁 之后 继续争抢所的时候 A又抢到锁了 this对象锁是一个非公平锁
*/
synchronized (this) {
if (money < 1000) {
System.out.println("余额不足!");
break;
}
money-= 1000;
System.out.println(Thread.currentThread().getName() + "取出1000块" + "当前余额 " + money);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}