/*
需求: 模拟3个窗口同时在售50张 票 。
问题1 :为什么50张票被卖出了150次?
出现 的原因: 因为num是非静态的,非静态的成员变量数据是在每个对象中都会维护一份数据的,三个线程对象就会有三份。
解决方案:把num票数共享出来给三个线程对象使用。使用static修饰。
问题2: 出现了线程安全问题 ?
线程 安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的。
java线程同步机制的方式:
方式一:同步代码块
同步代码块的格式:
synchronized(锁对象){
需要被同步的代码...
}
同步代码块要注意事项:
1. 任意的一个对象都可以做为锁对象。
2. 在同步代码块中调用了sleep方法并不是释放锁对象的。
3. 只有真正存在线程安全问题的时候才使用同步代码块,否则会降低效率的。
4. 多线程操作的锁 对象必须 是唯一共享 的。否则无效。
需求: 一个银行账户5000块,两夫妻一个拿着 存折,一个拿着卡,开始取钱比赛,每次只能取一千块,要求不准出现线程安全问题。
方式二:同步函数
出现线程安全问题的根本原因:
1. 存在两个或者两个以上 的线程对象,而且线程之间共享着一个资源。
2. 有多个语句操作了共享资源。
*/
class Ticket extends Thread {
static int tickets = 100;// 静态票数
static Object object = new Object(); // 静态锁(只要是对象都可以充当锁)!!!静态锁!!!!
public Ticket(String name) {
super(name);
}
@Override
public void run() {
while (true) {
// 同步代码块
synchronized (object) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName()
+ "卖出了第 " + tickets + "张票");
tickets--;
} else {
System.out.println(Thread.currentThread().getName() + "售罄");
break;
}
}
}
}
}
public class Demo2 {
public static void main(String[] args) {
// 创建三个线程对象,模拟三个窗口
Ticket ticket1 = new Ticket("窗口一");
Ticket ticket2 = new Ticket("窗口二");
Ticket ticket3 = new Ticket("窗口三");
// 开启线程售票
ticket1.start();
ticket2.start();
ticket3.start();
}
}
线程安全同步问题
最新推荐文章于 2024-04-11 19:54:55 发布