多线程例子 — 窗口卖票

多线程的创建--窗口买票两种实现方式

创建多线程方法一: 同步代码块实现Runnable接口

1. 创建一个实现了Runnable接口的类

2. 实现类去实现Runnable中的抽象方法

3. 创建实现类的对象

4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象

5. 通过Thread类的对象调用start()

public class ThreadTest1 {
    public static void main(String[] args) {
        //创建实现类的对象
        MThead mThead = new MThead();
        //将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
        Thread t1 = new Thread(mThead);
        //通过Thread类的对象调用start(): 1.启动线程 2.调用当前线程的run()-->调用了Runnable类型的target()
        t1.setName("线程1");
        t1.start();
        Thread t2 = new Thread(mThead);
        t2.setName("线程2");
        t2.start();
        Thread t3 = new Thread(mThead);
        t3.setName("线程3");
        t3.start();

    }
}
class MThead implements Runnable{


    private static int ticket = 100;   //多个线程共享一个静态变量
    Object object = new Object(); //锁 任意一个类的对象 多个线程必须使用同一个锁  也可以用this
    @Override
    public void run(){
        while (true){

            synchronized(object){    //也可以用this
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }


                if (ticket>0){
                    System.out.println(Thread.currentThread().getName()+":买票,票号为:"+ ticket);
                    ticket--;
                }else {
                    break;
                }
            }
        }

    }
}

创建多线程方法二: 同步方法实现Runnable接口

如果操作共享数据的代码完整的声明在一个方法中,不妨将此方法声明同步的

public class tongbuRunnable {
    public static void main(String[] args) {
        //创建实现类的对象
        MThead mThead = new MThead();
        //将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
        Thread t1 = new Thread(mThead);
        Thread t2 = new Thread(mThead);
        Thread t3 = new Thread(mThead);
        //通过Thread类的对象调用start(): 1.启动线程 2.调用当前线程的run()-->调用了Runnable类型的target()
        t1.setName("线程1");
        t2.setName("线程2");
        t3.setName("线程3");

        t1.start();
        t2.start();
        t3.start();
    }
}
class MyThead implements Runnable{
    private static int ticket = 100;   //多个线程共享一个静态变量
    @Override
    public void run(){
        while (true){
            show();
        }

    }
    public synchronized void show(){ //同步监视器默认为this

            if (ticket>0){
                System.out.println(Thread.currentThread().getName()+":买票,票号为:"+ ticket);
                ticket--;
            }
    }
}

 

创建多线程方法三: 同步代码块继承Thread方式

1. 创建一个继承Thread类的子类

2. 重写Thread类的run() -->将此线程执行的操作声明在run()中

3. 创建Thread类的子类的对象

4. 通过此对象调用start()

class MulitThread extends Thread{
    private static int ticket = 100;   //多个线程共享一个静态变量
    private static Object object = new Object(); 
    @Override
    public void run(){
        while (true){

            synchronized(object){  //也可以使用当前类作为同步监视器 比如 MulitThread.class
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }


                if (ticket>0){
                    System.out.println(Thread.currentThread().getName()+":买票,票号为:"+ ticket);
                    ticket--;
                }else {
                    break;
                }
            }
        }

    }

}
public class ThreadTest{
    public static void main(String[] args) {
        MulitThread t1 = new MulitThread();
        MulitThread t2 = new MulitThread();
        MulitThread t3 = new MulitThread();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();

    }
}

创建多线程方法四: 同步方法继承Thread方式

class MuliThread extends Thread{
    private static int ticket = 100;   //多个线程共享一个静态变量

    @Override
    public void run(){
        while (true){
            sho();
        }
    }
    public static synchronized void sho(){ //此时同步监视器为MuliThread.class

        if (ticket>0){
            System.out.println(Thread.currentThread().getName()+":买票,票号为:"+ ticket);
            ticket--;
        }
    }

}
public class Tongbu1{
    public static void main(String[] args) {
        MulitThread t1 = new MulitThread();
        MulitThread t2 = new MulitThread();
        MulitThread t3 = new MulitThread();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();

    }
}

 

比较创建线程的两种方式:

两者区别:

开发中,优先选择Runnable接口的方式

1. 继承Thead类方法 ticket需要加static修饰ticket,而Runnable方法直接new的唯一一个参数对象传递到多个Thread中,具有天然的共享性

2. 继承在Java类的成面具有一定局限性(没有多继承), 实现的方式没有类单继承性的局限性

两者联系:public class Thread implement Runnable

两种方式都需要重写run(),将线程要执行的逻辑重写在run()里面。

关于同步方法的总结:

1.同步方法仍然及到同步监视器,只是不需要我们显式的声明。

2.非静态的同步方法,同步监视器是:this静态的同步方法

3. 静态的同步方法,同步监视器是:当前类本身

 

posted @ 2021-05-18 15:53  sukezmy  阅读(263)  评论(0)    收藏  举报