Contents
20.6. 线程安全¶
多线程同步
为了防止多线程对临界资源的访问有时会导致数据的不一致性,Java提供了“互斥”机制,可以为这些 资源对象加上一把“互斥锁”,在任一时刻只能由一个线程访问,即使该线程出现阻塞,该对象的被锁 定状态也不会解除,其他线程仍不能访问该对象,这就多线程同步。线程同步保证线程安全的重要手 段,但是线程同步客观上会导致性能下降。
synchronized方法
代码示例
package com.a51work.cn;
//机票数据库
public class TocketDB {
//机票的数量
private int ticketCount = 5;
// 获得当前机票数量
public synchronized int getTicketCount() {
return ticketCount;
}
public synchronized void sellTicket() {
try {
//等于用户付款
//线程休眠,阻塞当前线程,模拟等待用户付款
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.printf("第%d 号票,已经售出\n", ticketCount);
ticketCount--;
}
public static void main(String[] args) {
TocketDB db = new TocketDB();
//创建线程1
Thread t1 = new Thread(() -> {
//查询是否有票
while (true) {
int currTicketCount = db.getTicketCount();
if (currTicketCount > 0) {
db.sellTicket();
}else {
// 无票退出
System.out.println("票已经售完...");
break;
}
}
});
//开始线程t1
t1.start();
//创建线程2
Thread t2 = new Thread(() -> {
//查询是否有票
while (true) {
int currTicketCount = db.getTicketCount();
if (currTicketCount > 0) {
db.sellTicket();
}else {
// 无票退出
break;
}
}
});
//开始线程t2
t2.start();
}
}
/*
第5 号票,已经售出
第4 号票,已经售出
第3 号票,已经售出
第2 号票,已经售出
第1 号票,已经售出
票已经售完...
* */
synchronized语句
代码示例
public static void main(String[] args) {
TocketDB2 db = new TocketDB2();
//创建线程1
Thread t1 = new Thread(() -> {
//查询是否有票
while (true) {
synchronized (db) {
int currTicketCount = db.getTicketCount();
if (currTicketCount > 0) {
db.sellTicket();
} else {
// 无票退出
System.out.println("票已经售完...");
break;
}
}
}
});
//开始线程t1
t1.start();
//创建线程2
Thread t2 = new Thread(() -> {
//查询是否有票
while (true) {
synchronized (db) {
int currTicketCount = db.getTicketCount();
if (currTicketCount > 0) {
db.sellTicket();
} else {
// 无票退出
System.out.println("票已经售完...");
break;
}
}
}
});
//开始线程t2
t2.start();
}
}