[Java基础]线程同步之卖票案列分析

Posted Wecccccccc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Java基础]线程同步之卖票案列分析相关的知识,希望对你有一定的参考价值。

案列:
卖票。

需求:
某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票。

代码如下:

package SellTicketPack;

public class SellTicket implements Runnable{
    private int tickets = 100;

    @Override
    public void run() {
        while (true) {

            if (tickets > 0) {
                System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                tickets--;
            }
        }
    }
}
package SellTicketPack;

public class SellTicketDemo {
    public static void main(String[] args)
    {
        SellTicket st = new SellTicket();

        Thread t1 = new Thread(st,"窗口1");
        Thread t2 = new Thread(st,"窗口2");
        Thread t3 = new Thread(st,"窗口3");

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

在这里插入图片描述
代码如下:

package SellTicketPack;

public class SellTicket implements Runnable{
    private int tickets = 100;

    @Override
    public void run() {
        while (true) {

            if (tickets > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                tickets--;
            }
        }
    }


}

package SellTicketPack;

public class SellTicketDemo {
    public static void main(String[] args)
    {
        SellTicket st = new SellTicket();

        Thread t1 = new Thread(st,"窗口1");
        Thread t2 = new Thread(st,"窗口2");
        Thread t3 = new Thread(st,"窗口3");

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

}

在这里插入图片描述

在这里插入图片描述
代码如下:

package SellTicketPack;

public class SellTicket implements Runnable{
    private int tickets = 100;
    private Object obj = new Object();
    @Override
    public void run() {
        while (true) {

            synchronized (obj) {
                if (tickets > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                    tickets--;
                }
            }
        }
    }

}

在这里插入图片描述

同步方法:
代码如下:

package SellTicketPack;

public class SellTicket implements Runnable{
    private int tickets = 100;
    private Object obj = new Object();
    private int x = 0;
    @Override
    public void run() {
        while (true) {
            if (x%2==0) {
//                synchronized (obj)
                synchronized (this)
                {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                        tickets--;
                    }
                }
            }
            else
            {
//                synchronized (obj) {
//                    if (tickets > 0) {
//                        try {
//                            Thread.sleep(100);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
//                        tickets--;
//                    }
//                }

                sellTicket();
            }
            x++;
        }
    }


//    private void sellTicket() {
//        synchronized (obj) {
//            if (tickets > 0) {
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
//                tickets--;
//            }
//        }
//    }

    private synchronized void sellTicket() {
        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
            tickets--;
        }
    }

}

同步静态方法:
代码如下:

package SellTicketPack;

public class SellTicket implements Runnable{
//    private int tickets = 100;
    private static int tickets = 100;
    private Object obj = new Object();
    private int x = 0;
    @Override
    public void run() {
        while (true) {
            if (x%2==0) {
//                synchronized (obj)
//                synchronized (this)
                synchronized (SellTicket.class)
                {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                        tickets--;
                    }
                }
            }
            else
            {
//                synchronized (obj) {
//                    if (tickets > 0) {
//                        try {
//                            Thread.sleep(100);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
//                        tickets--;
//                    }
//                }

                sellTicket();
            }
            x++;
        }
    }


//    private void sellTicket() {
//        synchronized (obj) {
//            if (tickets > 0) {
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
//                tickets--;
//            }
//        }
//    }

    private static synchronized void sellTicket() {
        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
            tickets--;
        }
    }

}

在这里插入图片描述

代码如下:

package SellTicketPack02;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SellTicket implements Runnable{

        private int tickets = 100;
        private Lock lock = new ReentrantLock();

        @Override
        public void run() {
            while (true) {
                try{
                    lock.lock();
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                        tickets--;
                    }
                }finally {
                    lock.unlock();
                }
            }
        }
    }


package SellTicketPack02;

public class SellTicketDemo {
        public static void main(String[] args)
        {
            SellTicket st = new SellTicket();

            Thread t1 = new Thread(st,"窗口1");
            Thread t2 = new Thread(st,"窗口2");
            Thread t3 = new Thread(st,"窗口3");

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


以上是关于[Java基础]线程同步之卖票案列分析的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程:线程同步详解

多线程之同步代码块与同步函数

Java多窗口卖票问题详解

Java22线程创建(卖票),线程同步(卖包子)

java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)

Java代码质量改进之:使用ThreadLocal维护线程内部变量