多线程并发上锁之后依然出现问题

问题遇到的现象和发生背景

package Unsafe;

public class UnsafeTicket {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
Thread thread = new Thread(buyTicket,"学生");
Thread thread2 = new Thread(buyTicket,"社会人士");
Thread thread3 = new Thread(buyTicket,"黄牛");
thread.start();
thread2.start();
thread3.start();
}
}

class BuyTicket implements Runnable{
private int ticketNumbers = 10;
private boolean flag = true;

@Override
public void run() {
    while(flag){
        try {
            buy();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
public synchronized void buy() throws InterruptedException {
  if(ticketNumbers <= 0){
      flag =false;
  }
  Thread.sleep(100);
    System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNumbers--);
}

}

用代码块功能插入代码,请勿粘贴截图
运行结果及报错内容

买的票数依然有负的,

我的解答思路和尝试过的方法

加了synchronized也没用

我想要达到的结果

正常买票,不会买到负的

当flag=false 时,题主没有return,导致等于0时还会往下走 将票数量减一


public synchronized void buy() throws InterruptedException {
  if(ticketNumbers <= 0){
      flag = false;
      return;
  }
  Thread.sleep(100);
    System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNumbers--);
}