class Test{
public static void main(String[] args){
TestThread t = new TestThread();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
}
class TestThread implements Runnable{
private int tickets = 20;
public void run(){
while(true){
sale();
}
}
public synchronized void sale(){
if(tickets > 0){
try{
Thread.sleep(10);
}
catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println(Thread.currentThread().getName()
+ " is salling ticket " + tickets--);
}

}
输出:
Thread-0 is salling ticket 20
Thread-0 is salling ticket 19
Thread-0 is salling ticket 18
Thread-0 is salling ticket 17
Thread-0 is salling ticket 16
Thread-0 is salling ticket 15
Thread-0 is salling ticket 14
Thread-0 is salling ticket 13
Thread-0 is salling ticket 12
Thread-0 is salling ticket 11
Thread-0 is salling ticket 10
Thread-0 is salling ticket 9
Thread-0 is salling ticket 8
Thread-0 is salling ticket 7
Thread-0 is salling ticket 6
Thread-0 is salling ticket 5
Thread-0 is salling ticket 4
Thread-0 is salling ticket 3
Thread-0 is salling ticket 2
Thread-0 is salling ticket 1tickets数目大的话可能会输出 两个 Thread 问题:    1.在这个程序中,同步方法public synchronized void sale(){...} 中的 Thread.sleep(10);
      在这里Thread.sleep(10);之后会切换到其他进程 ,但由于其他线程均只有一个方法,且是同步的,
      其他线程也不能进入该方法,所以Thread.sleep(10);在这里相等于没起作用。
      上面的分析都正确吗?
    2.关于输出结果:去掉上面程序的 Thread.sleep(10);  同步函数sale()中的if语句只执行一次
      就会解锁,输出结果应该是4个线程交错啊?
public synchronized void sale(){ 
if(tickets > 0){
System.out.println(Thread.currentThread().getName()
+ " is salling ticket " + tickets--);
}

解决方案 »

  1.   

    一个鸡蛋四只手,每只手的任务都是去握住鸡蛋然后放开。
    sale方法就是那个鸡蛋,四个线程就是四只手;一只手先握住了鸡蛋(获得对象锁),停顿了N毫秒(保持锁)(其他线程等待这个线程释放锁),然后放开(释放锁)。这时鸡蛋没锁,4只手都可以去握(申请对象锁),但总有一只手会先握到(获得锁)但那只手能握到(哪个线程先获得锁)是不确定的,他是由调度算法来调度的,这就可能出现一种情况,一直是同一只手握到。你的代码1和代码2区别仅仅在于每次握住要握多久,其他无差别
      

  2.   

    1、你理解的没错,Thread.sleep(10)这个确实没用
    2、你锁定的是sale()方法,只有当你退出这个方法是才会解锁;因为你是多个线程同时执行这个同步方法,理论上是当你解锁时,所有线程都有机会获得这把锁,但最终是哪个线程获得,这个是系统决定的,每次执行都可能不一样。这个不是你能控制的。