美文网首页
java多线程 四个窗口卖10张票,遇到的一些问题

java多线程 四个窗口卖10张票,遇到的一些问题

作者: 沉默的小象 | 来源:发表于2021-04-24 12:38 被阅读0次
  • 启用了四个线程,但是只有一个窗口在卖票。
public class SellTicketTest {
    public static void main(String[] args) {
        TicketSell t1 = new TicketSell();
        TicketSell t2 = new TicketSell();
        TicketSell t3 = new TicketSell();
        TicketSell t4 = new TicketSell();

        t1.setName("第一号窗口");
        t2.setName("第二号窗口");
        t3.setName("第三号窗口");
        t4.setName("第四号窗口");

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


}



class TicketSell extends Thread {
    private static int ticket = 10;

    @Override
    public void run() { //在循环开始外围进行同步代码块,当第一个线程进入的时候,因为一直在循环所以代码没有执行完
        //其他的线程不能执行该同步代码块的代码
        synchronized (TicketSell.class) {
            while (ticket > 0) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(this.getName() + "卖出第 " + ticket + "号票");
                ticket--;
            }
        }
    }
}
image.png
在循环开始外围进行同步代码块,当第一个线程进入的时候,因为一直在循环所以代码没有执行完,其他的线程不能执行该同步代码块的代码。所以,在写同步代码块的时候,注意不要把循环也包含在内。
  • 对代码进行修改后,问题二:卖出负数号票
class TicketSell extends Thread {
    private static int ticket = 10;

    @Override
    public void run() { 
        while (ticket > 0) {
            synchronized (TicketSell.class) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(this.getName() + "卖出第 " + ticket + "号票");
                ticket--;
            }
        }
    }
}
image.png

2,3,4号线程,满足ticket>0,会进入while循环,但是此刻1号线程正在执行同步代码块,待其执行完后, 2,3,4号线程会分别执行同步代码块。导致出现负数。

  • 继续修改代码,最终正确执行。
class TicketSell extends Thread {
    private static int ticket = 20;

    @Override
    public void run() {
        while (true) {
            synchronized (TicketSell.class) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(this.getName() + "卖出第 " + ticket + "号票");
                    ticket--;
                } else {
                    break;
                }
            }
        }
    }
}
image.png

相关文章

网友评论

      本文标题:java多线程 四个窗口卖10张票,遇到的一些问题

      本文链接:https://www.haomeiwen.com/subject/jknkrltx.html