Tread安全问题的处理方式
1.使用synchronized同步代码块
下面我用一个简单的车票售卖的案例简单讲述一下
(1)一个车15张票
(2)三个售票窗口同时售卖
(3)使用程序来获取和打印票号
1.使用synchronized同步代码块
public class thread02 implements Runnable{
private Integer tickets=15;
Object obj = new Object();
@Override
public void run() {
while(tickets>0){
synchronized (obj) {
if (tickets > 0) {
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName() + "正在卖第" + tickets + "张票");
tickets--;
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
return;
}
}
}
System.out.println("本次列车票已售罄");
}
}
2.使用同步方法
public class thread02 implements Runnable {
private Integer tickets = 15;
@Override
public void run() {
while (tickets > 0) {
if (tickets > 0) {
payTickets();
} else {
return;
}
}
System.out.println("本次列车票已售罄");
}
public synchronized void payTickets() {
if (tickets > 0) {
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName() + "正在卖第" + tickets + "张票");
tickets--;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3.使用Lock锁机制
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class thread02 implements Runnable {
//定义一个多个线程共享的票源
private Integer ticket = 15;
//1.在成员位置创建一个ReentrantLock对象
Lock l = new ReentrantLock();
//设置线程任务:卖票
@Override
public void run() {
//使用死循环,让卖票操作重复执行
while(true){
//2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
l.lock();
//先判断票是否存在
if(ticket>0){
//提高安全问题出现的概率,让程序睡眠
try {
Thread.sleep(10);
//票存在,卖票 ticket--
System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁
l.unlock();//无论程序是否异常,都会把锁释放
}
}
}
}
}
测试运行
public static void main(String[] args) {
thread02 ticketRunnable = new thread02();
Thread thread01 = new Thread(ticketRunnable,"窗口1");
Thread thread02 = new Thread(ticketRunnable,"窗口2");
Thread thread03 = new Thread(ticketRunnable,"窗口3");
thread01.start();
thread02.start();
thread03.start();
}
运行结果对比
同步前
同步后
好了,小鑫的分享就到这里了,希望大家评论