多线程模拟售票
1.编写一个多线程的程序,模拟火车站卖票系统。共有4个窗口,同时卖出100张火车票
public static void main(String[] args) {MyThread m=new MyThread();//创建四个线程模拟四个售票员A,B,C,D Thread t1=new Thread(m,"A"); Thread t2=new Thread(m,"B"); Thread t3=new Thread(m,"C"); Thread t4=new Thread(m,"D"); t1.start(); t2.start(); t3.start(); t4.start(); }
然后是售票的过程
public class MyThread implements Runnable{ private int ticket=100; private String name; public void run() { for(int i=0;i<100;i++) {try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if(ticket>0) {System.out.println(Thread.currentThread().getName()+"卖出一张,还剩"+(--ticket));} } } public MyThread(String name){this.setName(name);} public MyThread(){} public int getTicket() { return ticket; } public void setTicket(int ticket) { this.ticket = ticket; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
但是我们发现一个问题,其中有重复的,这是为什么?因为线程在竞争的过程中,CPU的切换是非常快的,可能线程1正好执行完的时候,线程已经切换到了线程2,此时又再执行了一次,导致跳过了一张票没有卖出,或者,当线程1恰好正好将要执行但还没执行的时候,线程已经切换到了线程2,此时因为线程1并没有进行操作,线程2卖出了重复的同一张票以后,才执行了--maipiao,导致出现了同一张票重复销售的情况。那么我们怎么解决这个问题呢
这里就需要线程锁,也就是同步代码块
语法:
synchronized(同步对象){
需要同步的代码
}
同步方法:使用synchronized修饰的方法被称为同步方法
访问权限修饰符 【static】 【final】 【synchronized】 返回值类型 方法名称(【参数列表】)【throws 异常...】{}
同步带来最大的好处就是使线程变得安全了。
即:
package title1; public class MyThread implements Runnable{ private int ticket=100; private String name; public void run() { for(int i=0;i<100;i++) {try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (this) { if(ticket>0) {System.out.println(Thread.currentThread().getName()+"卖出一张,还剩"+(--ticket));} } } } public MyThread(String name){this.setName(name);} public MyThread(){} public int getTicket() { return ticket; } public void setTicket(int ticket) { this.ticket = ticket; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
这样,就不会出现重复卖一张票或者跳过某张票了