多线程(解决)火车票窗口售票的问题
铁道部发布了一个售票任务,要求销售1000张票,要求有5个窗口来进行销售,请编写多线程程序来模拟这个效果
i. 窗口001正在销售第1000张票
ii. 窗口001正在销售第999张票
iii. 窗口002正在销售第998张票
iv. 。。。
v. 窗口05正在销售第1张票
vi. 票已经销售完毕
解决一,使用同步代码块:
public class MySynchonized implements Runnable{
//定义1000张票,用静态定义是为了能让所有方法都能访问到tictet,否则报错
public static int ticket=1000;
//锁对象可以是java中任何对象,但是这个对象必须是多个线程共享的一个对象,且这个对象的值最好固定不变.
Object ob=new Object();
@Override
public void run() {
while(true){
//定义需要锁的地方
synchronized(ob){
if(ticket>=1){
System.out.println(Thread.currentThread().getName()+"正在售第"+ticket+"张票");
//每卖一张我就减少一张票
ticket--;
}else{
//卖完了退出循环
break;
}
}
}
}
}
//主方法
public class Synchonized {
public static void main(String[] args) {
MySynchonized r=new MySynchonized();
//因为是5个窗口,这里一个for循环就可以解决
//不用一个一个定义
for (int i = 1; i <=5; i++) {
Thread it=new Thread(r, "窗口"+i);
it.start();
}
}
}
解决二,使用同步方法:
public class SynchonizedMenthod implements Runnable{
//首先定义1000张票
public static int ticket=1000;
//重写任务方法
@Override
public void run() {
//循环体一直在卖票
while(true){
//如果为ture ,就是卖完了,直接退出循环
if(salaTicket()==true){
break;
}
}
}
//标记方法
public synchronized boolean salaTicket(){
//如果票还没卖完
if(ticket>=1){
System.out.println(Thread.currentThread().getName()+"正在售第"+ticket+"张票");
ticket--;
//返回false
return false;
}else{
//卖完了
//返回true
return true;
}
//主方法
public class Test {
public static void main(String[] args) {
SynchonizedMenthod sy=new SynchonizedMenthod();
for (int i = 1; i <=5; i++) {
Thread it=new Thread(sy, "窗口00"+i);
it.start();
}
}
}
解决三,使用重入锁:
public class MyrentantLock implements Runnable{
public static int ticket=1000;
/**
* 使用重入锁,在使用的时候会出现死锁现象,所以为了防止这种现象,配合try-finally使用,finally是会到最后都会执行的,优先级高于return
*语法为:
l.lock();
try{
需要锁的代码块;
}finally{
l.unlock
}
*
*/
//定义锁 ,名称为l
Lock l=new ReentrantLock();
//重写任务方法
@Override
public void run() {
while(true){
l.lock();
try {
if(ticket>=1){
System.out.println(Thread.currentThread().getName()+"正在售第"+ticket+"张票");
ticket--;
}else{
break;
}
} finally {
l.unlock();
}
}
}
}
public class Test {
public static void main(String[] args) {
MyrentantLock l=new MyrentantLock();
for (int i = 1; i <=5; i++) {
Thread t=new Thread(l, "窗口00"+i);
t.start();
}
}
}
这样免票就不会出现重复的现象了。