多线程实现买票问题
实现Runnable接口的方式实现四个线程卖100张火车票的问题
点击查看代码
public class TestTicket {
public static void main(String[] args) {
// 启动四个线程卖票。
TicketThread tt = new TicketThread();//一个线程对象
new Thread(tt).start();//启动四个线程,操作TicketThread类中的 tickets成员变量
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}
}
class TicketThread implements Runnable {
// 100张票。
private Integer tickets = 100;//争用资源..
@Override
public void run() {
while (tickets > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {//临界区,当某个线程进入临界区后,其它线程必需等该线程执行完毕后,才有机会进入到该代码块中
if(tickets>0) {//此处判断是为了避免出现负数的情况
System.out.println(Thread.currentThread() + " is saling ticket " + tickets);
tickets--;
}
}
}
}
}
点击查看代码
public class TestTicket2 {
public static void main(String[] args) {
// 启动四个线程卖票。
TicketThread2 t1 = new TicketThread2();
t1.start();
TicketThread2 t2 = new TicketThread2();
t2.start();
TicketThread2 t3 = new TicketThread2();
t3.start();
TicketThread2 t4 = new TicketThread2();
t4.start();
}
}
class TicketThread2 extends Thread {
private static Integer tickets = 100;//静态的变量隶属于类,不属于对象,多个对象共享的。
@Override
public void run() {
while (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
/*
this代表当前对象,我们创建了四个TicketThread2类的对象,this分别代码这四个对象;
相当于有四个对象分别上锁和开锁(厕所有四个门),所以不可取;
所以我们得为共享静态变量所属于的类上锁,即:TicketThread类上锁。
*/
synchronized (TicketThread2.class) {
if(tickets>0) {//此片判断是为了避免出现负数的情况
System.out.println(Thread.currentThread() + "卖出了第" + tickets + "张票");
tickets--;
}
}
}
}
}
点击查看代码
public class TestTicket3 {
public static void main(String[] args) {
Ticket ticket = new Ticket();
ticket.tickets = 150;
// 启动四个线程卖票。
TicketThread3 t1 = new TicketThread3(ticket);
t1.start();
TicketThread3 t2 = new TicketThread3(ticket);
t2.start();
TicketThread3 t3 = new TicketThread3(ticket);
t3.start();
TicketThread3 t4 = new TicketThread3(ticket);
t4.start();
}
}
//在Thread类中用成员代表火车票或定义静态变量都不合适的情况下,我们可以把火车票单独拿出来,然后传入到线程类中
class Ticket{//代表火车票
int tickets=100;
}
class TicketThread3 extends Thread {
Ticket ticket;
public TicketThread3(Ticket ticket){
this.ticket = ticket;
}
@Override
public void run() {
while (ticket.tickets > 0) {
synchronized (ticket) {
if(ticket.tickets>0) {//此片判断是为了避免出现负数的情况
System.out.println(Thread.currentThread() + " 已卖 " + ticket.tickets);
ticket.tickets--;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}