我只是编写一些代码来测试多个线程如何同步,但是我无法获得预期的结果。该代码可以启动3个线程,但是只能使用一个线程来处理共享资源。我的代码有什么问题。

class ThreadDemo1{
   public static void main (String[] args){
       MultiThread tt = new MultiThread();
       new Thread(tt).start();
       new Thread(tt).start();
       new Thread(tt).start();
   }
}
class MultiThread implements Runnable {
  int tickets = 100;
  Object _lock = new Object();
  public void run () {
    System.out.println(Thread.currentThread().getName());
    synchronized(_lock) {
      while (true) {
        if (tickets>0) {
          try {
            Thread.sleep(10);
          } catch (Exception e) {}
          System.out.println(Thread.currentThread().getName() + " is selling "+tickets--);
        }
      }
    }
  }
}

最佳答案

您正在按住锁在 sleep 。如果要这样做,则没有理由使用多线程。

public void run () {
    System.out.println(Thread.currentThread().getName());
    while(tickets > 0) {
        synchronized(_lock) {
            if (tickets > 0) {
                System.out.println(Thread.currentThread().getName() + " is selling " + tickets--);
            }
        }
        try {
            Thread.sleep(10);
        } catch (Exception e) {
        }
    }
}

我猜sleep是您处理的占位符。如果可能,您应该在同步块(synchronized block)内进行检查和递减,但是要在同步块(synchronized block)外进行冗长的处理。

为了使锁和多线程对您有用,您必须确保synchronized代码花费尽可能少的时间,因为该代码一次只能由一个线程运行。

在您的代码中,唯一没有有效单线程的是您的第一个System.println

仅供引用,考虑到这一点,如果您可以使打印的报表准确无误,但可能会出现问题,那么拥有以下内容会更好:
public void run () {
    System.out.println(Thread.currentThread().getName());
    while(tickets > 0) {
        int oldTickets = 0;
        synchronized(_lock) {
            if (tickets > 0) {
                oldTickets = tickets--;
            }
        }
        if(oldTickets > 0) {
            System.out.println(Thread.currentThread().getName() + " is selling " + oldTickets);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
            }
        }
    }
}

10-07 16:35
查看更多