韩顺平 java 第40讲 线程同步

时间:2021-05-16 21:05:29

线程深入理解

  1. 线程对象只能启动一个线程。不管是继承Thread,还是通过实现Runnable接口创建线程,它们的一个对象只能启动(即start())一次,否则就会有异常抛出。不能通过此方式实现多个线程跑起来。

问题:模拟一个机票售票系统,有三个售票点,在一天内卖出2000张票,(一共卖出2000张)。
这里要考虑,多线程并发会带来线程安全问题。本题中,有可能会出现同一张票被卖了多次。
如何解决?
解决问题的关键就是要保证容易出问题代码的原子性,所谓的原子性就是指:当a
线程在执行某段代码的时候,别的线程必须等到a线程执行完后,它才能执行这段代码。
java处理的方法就是在需要同步的代码段用下列包起来:

synchronized(Object){
    //你需要同步的代码
}

当某个线程在处理某段被同步的代码时,其他的线程就会被blocked,放入线程等待池。

package com.chen;

public class SellTickets {
    public static void main(String[] args) {
        TicketWindow window = new TicketWindow();

        Thread t1 = new Thread(window);
        Thread t2 = new Thread(window);
        Thread t3 = new Thread(window);

        t1.start();
        t2.start();
        t3.start();
    }
}
class TicketWindow implements Runnable{
    private int nums = 2000;

    public void run() {
        while(true){
            //这段要保证原子性
            synchronized(this){
                if(this.nums > 0){
                    System.out.println(Thread.currentThread().getName() + "正在销售第"+this.nums+"张票");
                    try {
                        Thread.sleep(700);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    this.nums--;
                }else{
                    break;
                }
            }
        }
    }
}