有个作业要求实现多个售票站卖火车票,我想把票设为静态变量,然后通过一个类方法来取票来保证同步,但是给类方法上锁以后,不同实例的线程取票时还会出错,卖出第-1张票,请问问题出在哪里呢?是类方法的调用方式有问题么?
代码如下:
public class Tickets extends Thread{
 private static int tickets=100;
 public static synchronized void sellOne(String name){
System.out.println(name+"_________"+(tickets--));
}
public void run(){
while(tickets>0)
{
String name=Thread.currentThread().getName();
sellOne(name);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new Tickets().start();
new Tickets().start();
new Tickets().start();
new Tickets().start();
}}

解决方案 »

  1.   

    竞态条件问题,while(tickets>0)与tickets--不是原子的当tickets等于1,两个线程同时发现tickets>0,都进了sellOne方法,就导致这个问题了
      

  2.   

    public static synchronized void sellOne(String name) {
    while (tickets > 0) {
    System.out.println(name + "_________" + (tickets--));
    }
    } public void run() {
    String name = Thread.currentThread().getName();
    sellOne(name);
    }
    这样应该ok了
      

  3.   

    当tickets=1时,两个线程同时去判断tickets发现他都大于0所以两个线程都调用sellOne方法,当一个线程执行完后另一个线程在去执行(注意这里后一个线程他是停在sellOne方法上的,所以他不会在跑回去判断tickets是否大于0而是直接去实行sellOne方法,就出现-1了)。
      

  4.   

    可能不是同时 而是前一个线程还没执行到tickets--时,下一个线程又去判断tickets是否大于0。
      

  5.   

    package comticket;public class NewThreadTicket implements Runnable {
    private int ticket = 100;
    // 在java中所有的对象都是一把锁
    //private Object obj = new Object();
    public void run() {
    while (ticket!=0) {
    sell();
    /*
     * //枷锁 synchronized (obj) { if (ticket > 0) { try {
     * Thread.sleep(30); } catch (InterruptedException e) {
     * e.printStackTrace(); }
     * System.out.println(Thread.currentThread().getName() + "卖出第" +
     * ticket + "张"); ticket--; }
     */
    }
    } public synchronized void sell() {
    if (ticket > 0) {
    try {
    Thread.sleep(30);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "卖出第"
    + ticket + "张");
    ticket--;
    }
    }
    }
    package comticket;public class Test {
    public static void main(String[] args) {
    //创建对象
    NewThreadTicket ntt = new NewThreadTicket();
    //创建四个线程
    new Thread(ntt).start();
    new Thread(ntt).start();
    new Thread(ntt).start();
    new Thread(ntt).start();
    }
    }
      

  6.   

    只是锁定了sellOne,不能同时进sellOne,但是run方法并没有锁啊,他们可以同时进run,执行while判断
      

  7.   

    public static synchronized void sellOne(String name){
    if(tickets>0)
    System.out.println(name+"_________"+(tickets--));
    }