1、场景:模拟12306网站,多线程抢票系统
使用同步方法
2、分析
Thread的构造方法中持有一个Runnable对象
需要传入哪个线程对象在订票,也就是说synchronized同步方法必须放在Web12306这个类,因为购票时需要锁Web12306,而不是锁Passenger。Passenger继承了Thread,是一个代理对象。
//Web12306作为线程的目标对象target public Passenger(Runnable target,String name,int seats) { super(target, name); this.seats = seats; }
3、代码
package com.dhu.thread.cinema;
/**
* Passenger 继承了Thread,作为子代理类对象
* @author zhou
*
*/
class Passenger extends Thread{
private int seats; //订的位置
public Passenger(int seats) {
this.seats = seats;
}
//Web12306作为线程的目标对象target
public Passenger(Runnable target,String name,int seats) {
super(target, name);
this.seats = seats;
}
public int getSeats() {
return this.seats;
}
}
class Web12306 implements Runnable{
private int available; //可选的座位
private String name; //名
public Web12306(int available, String name) {
this.available = available;
this.name = name;
}
public int getAvailable() {
return available;
}
public void setAvailable(int available) {
this.available = available;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() {
Passenger p = (Passenger) Thread.currentThread(); //获取当前正在操作的线程
boolean flag = this.bookTicket(p.getSeats()); //需要传入哪个线程对象在订票
if(flag) {
System.out.println("出票成功," + Thread.currentThread().getName() + "购票位置为: " + p.getSeats());
}else {
System.out.println("出票失败," + Thread.currentThread().getName() + "位置不够");
}
}
//购票方法
public synchronized boolean bookTicket(int seats) {
System.out.println("可用位置: " + available);
if(this.available < seats) {
return false;
}
this.available -= seats;
return true;
}
}
public class Tickets12306 {
public static void main(String[] args) {
Web12306 web = new Web12306(3, "东华");
new Passenger(web, "老高", 2).start();
new Passenger(web, "老王", 2).start();
}
}
4、运行结果