java 多线程详解二 买票示例

原创 2016年08月30日 21:53:55

问题描述:写一个卖票程序,假设有10张票(实际可能有几百万张),有3个窗口同时售票,打印显示卖出的每张票。

(1)实现方式一(错误示例):

public class Ticket implements Runnable {
    int num = 10;

    @Override
    public void run() {
        while (num>0) {
            num--;
            System.out.println(Thread.currentThread().getName() + ":" + num);
        }
    }
}
public class TicketDemo {
    public static void main(String[] args) {
        Ticket ticket=new Ticket();
        Thread thread1=new Thread(ticket);
        Thread thread2=new Thread(ticket);
        Thread thread3=new Thread(ticket);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
Thread-0:9
Thread-0:8
Thread-0:7
Thread-0:6
Thread-0:5
Thread-0:4
Thread-0:3
Thread-0:2
Thread-0:1
Thread-0:0

Process finished with exit code 0

发现结果符合题意,依次打印出车票。结果正确。下面我们修改程序,每卖出一张票休眠200毫秒(根据电脑配置不同休眠时间自己调整)。


 public class Ticket implements Runnable { 
    int num = 10;
    @Override
    public void run() {
        while (true) {
             try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } 
            if(num>0){
            num--;
            System.out.println(Thread.currentThread().getName() + ":" + num);
            }
        }
    }
}
Thread-0:9
Thread-1:8
Thread-2:8
Thread-0:7
Thread-1:6
Thread-2:5
Thread-0:4
Thread-1:3
Thread-2:2
Thread-0:1
Thread-2:0
Thread-1:-1
Thread-0:-2

Process finished with exit code 0

安全问题:我们发现当睡眠200毫秒后程序出现了问题,我们多卖出了8,-1,-2 三张票。出现了安全问题。

原因:两个或以上数量的线程同时执行了相同的代码,同时卖出一样的票。导致同样的票买了两次或多次。

2.实现方式二(安全问题解决方案)

解决方案:同步锁

public class Ticket implements Runnable {
    int num = 10;
Object object=new Object();
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (object){
                if (num>0) {
                    num--;
                    System.out.println(Thread.currentThread().getName() + ":" + num);
                }
            }

        }
    }
}

现在我们的程序就可以成功运行了。

总结:
1.多线程存在线程安全问题。
2.可以用同步锁的方式解决同步问题。

3.线程安全问题产生的原因

1,多个线程在操作共享的数据。
2,操作共享数据的线程代码有多条。

解决思路;
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,
其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。

在java中,用同步代码块就可以解决这个问题。

同步代码块的格式:
synchronized(对象)
{
需要被同步的代码 ;
}

4.同步的好处和弊端

同步的好处:解决了线程的安全问题。

同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。

5.同步的前提:
同步中必须有多个线程并使用同一个锁。

Java多线程示例:4个售票员卖1000张火车票

//售票员 import java.util.Iterator; import java.util.Map; public class TicketSaler implements Runnabl...
  • huhai463127310
  • huhai463127310
  • 2011年11月17日 01:14
  • 15082

JAVA多线程售票问题

//定义一个类实现Runnable接口,定义一个需要同步的售票方法,然后重写run方法调用售票的sale方法 class SaleTicket implements Runnable{ priva...
  • VLTIC
  • VLTIC
  • 2011年12月24日 16:37
  • 9577

java多线程实现售票

package com.gxk.thread; class ticketThread extends Thread { private static int ticket = 50; priv...
  • gukunkun
  • gukunkun
  • 2016年11月27日 19:40
  • 1292

java多线程买票,同步锁

经典多线程例子:售卖火车票 要求销售1000张票,要求有10个窗口来进行销售, 请编写多线程程序来模拟这个效果public class MyTask implements Runnable{ ...
  • FlyingZhLunasea
  • FlyingZhLunasea
  • 2017年06月07日 10:32
  • 669

Java多线程实现简单的售票程序

设计一个多线程程序如下:设计一个火车售票模拟程序。假如火车站要有100张火车票要卖出,现在有5个售票点同时售票,用5个线程模拟这5个售票点的售票情况 1、要求打印出每个售票点所卖出的票号 ...
  • qq_35619711
  • qq_35619711
  • 2017年05月09日 11:48
  • 823

Java多线程4—线程同步问题+火车票售票系统

在上一篇文章中写到了许多线程共享同一数据,这种情况在现实的生活中也是经常发生的,比如火车站的火车票售票系统。火车票售票系统是一个常年运行的系统,为了满足乘客的需求,我们不能只设一个窗口,必须设很多的售...
  • mengxiangyue
  • mengxiangyue
  • 2011年10月13日 19:44
  • 19878

Java多线程—两种卖票

public class MyThread1 extends Thread{ private int ticket=10; public void run() { for(int i=0;i...
  • LY_624
  • LY_624
  • 2016年11月15日 09:36
  • 1113

Java多线程售票问题

1、代码 public class Test { public static void main(String[] args) { Tickets tickets = new Ticke...
  • vinegar93
  • vinegar93
  • 2016年05月19日 11:01
  • 1141

Java多线程同步机制在售票系统的实现

  • 2008年09月05日 17:32
  • 161KB
  • 下载

Java多线程应用之火车站售票

在我们的现实生活中,去火车站买票是一件很平常的事,但是你们想过吗,比如我们从一个售票处买了一张票的话,那么其他的售票点就不能找到这张票了,这样就可以保证每个人买的票不会一样,这是通过java的多线程功...
  • Story__struggle
  • Story__struggle
  • 2016年08月11日 12:52
  • 1076
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java 多线程详解二 买票示例
举报原因:
原因补充:

(最多只允许输入30个字)