多线程中的经典例题---卖票

Posted 杀手不太冷!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程中的经典例题---卖票相关的知识,希望对你有一定的参考价值。

多线程中的经典例题—卖票

使用Runnable接口创建线程

使用Runnable接口创建线程的时候,可以直接创建一个接口,然后实现内部的run方法,最后让接口对象作为Thread线程类的构造器的一个参数;也可以写一个Runnable接口的实现类,然后实现Runnable接口内部的run方法,然后让这个实现类作为Thread线程类的构造器的一个参数,其实也即是间接的让Runnable接口作为Thread线程类的构造器的一个对象;这里用的是第二种方式,创建一个Runnable接口的实现类,然后让这个实现类作为Thread线程类的构造器的一个对象,如下图:

在这里插入图片描述

可以从JVM的层面上理解上面所说的多个线程共用一个ticket,所以ticket不用声明成是static静态变量这句话:因为在堆区中只创建了一个w3对象,并且每个线程启动的时候用的都是w3对象里的run方法,所以栈中只有一个run方法对应的栈帧,这个栈帧的局部变量表中也只有一个ticket成员变量,所有的线程启动的时候都会用到这个ticket成员变量。

把synchronized加到方法上,如下图:

在这里插入图片描述

上图的java代码如下:

package org.xzy;
class Window3 implements Runnable{
    private int ticket=100;
    Object obj=new Object();
    @Override
    public void run() {
        while(ticket>0) {
            show();
        }
    }
    public synchronized void show(){
        if(ticket>0) {//在同步代码块中一定要加上if(ticket>0)这个判断条件
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+ticket);
            ticket--;
        }
    }
}
public class Test5 {
    public static void main(String[] args) {
        Window3 w3 = new Window3();
        Thread th1 = new Thread(w3,"窗口1");
        Thread th2 = new Thread(w3,"窗口2");
        Thread th3 = new Thread(w3,"窗口3");
        th1.start();
        th2.start();
        th3.start();
    }
}

无论是把synchronized关键字加到方法上还是不加到方法上,结果都一样,如下图:

在这里插入图片描述

使用Thread线程类的子类创建对象

创建一个类,让这个类继承Thread线程类,这个类就叫做Thread线程类的子类,然后重写这个子类中的run方法,创建这个子类的对象,其实也就相当于是创建Thread线程类的对象了,就相当于创建了一个线程,如下图:

在这里插入图片描述

上图的java代码如下:

package org.xzy;


public class Test7 {
    public static void main(String[] args) {
        Window5 w1=new Window5();
        Window5 w2=new Window5();
        Window5 w3=new Window5();
        w1.setName("窗口一");
        w2.setName("窗口二");
        w3.setName("窗口三");
        w1.start();
        w2.start();
        w3.start();
    }
}
class Window5 extends Thread{
    private static int ticket=100;
    @Override
    public void run() {
        while(ticket>0) {
            show();
        }
    }
    private static synchronized void show() {
        if(ticket>0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":卖票,票号为"+ticket);
            ticket--;
        }
    }
}

执行结果,如下图:

在这里插入图片描述

注意:只要是想创建线程类,那么肯定会直接或者间接地使用到Thread线程类去创建线程。

以上是关于多线程中的经典例题---卖票的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程:线程同步详解

iOS开发系列-线程同步技术

多线程卖票代码

Java 多线程实现多个窗口同时卖票

Java多窗口卖票问题详解

多线程(多窗口卖票例子)