多线程用了锁之后总是被一个线程强占

多线程用了锁之后总是被一个线程强占

public class Test04_2 {
    public static void main(String[] args) {
        Runnable qiangPiao = new QiangPiao();
        Runnable qiangPiao1 = new QiangPiao();
        Runnable qiangPiao2 = new QiangPiao();
        Thread t1 = new Thread(qiangPiao,"小青青");
        Thread t2 = new Thread(qiangPiao1,"黄牛党");
        Thread t3 = new Thread(qiangPiao2,"抢票代购");
        t1.start();
        t2.start();
        t3.start();
    }
}
class QiangPiao implements Runnable{
    static int piao = 10;

    @Override
    public synchronized void run() {
        synchronized (QiangPiao.class) {
            for (int i = 0; i < 10; i++) {
                if (piao == 0) {
                    break;
                }
                piao--;
                System.out.println(Thread.currentThread().getName() + "抢到了第" + (i + 1) + "张票,剩余" + piao + "张票!");
            }
        }
    }
}

run 方法 不能用 synchronized 修饰,这是同步方法,那肯定是 其中一个线程再占用了
修改如下:

public class Main {

    public static void main(String[] args) {
        Runnable qiangPiao = new QiangPiao();
        Runnable qiangPiao1 = new QiangPiao();
        Runnable qiangPiao2 = new QiangPiao();
        Thread t1 = new Thread(qiangPiao,"小青青");
        Thread t2 = new Thread(qiangPiao1,"黄牛党");
        Thread t3 = new Thread(qiangPiao2,"抢票代购");
        t1.start();
        t2.start();
        t3.start();

    }
}

class QiangPiao implements Runnable{
    static int piao = 10;

    @Override
    public void run() {
        while(true){
            if (piao == 0) break;
            int current;
            synchronized (this){
                piao--;
                current = 10 - piao;
            }
            System.out.println(Thread.currentThread().getName() + "抢到了第" + current + "张票,剩余" + (10 - current) + "张票!");
        }

    }
}

  1. 同步代码块和同步方法使用其一就可
  2. 锁应该写在你的循环体里面,不然你一个线程进去锁住;谁抢到进去的机会,就全给执行完了。
     @Override
     public void run() {
     for (int i = 0; i < 10; i++) {
           synchronized (QiangPiao.class) {
                 if (piao == 0) {
                     break;
                 }
                 piao--;
                 System.out.println(Thread.currentThread().getName() + "抢到了第" + (i + 1) + "张票,剩余" + piao + "张票!");
           }
     }
    }