synchronized 函数中 Thread.sleep 作用
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 1
tickets数目大的话可能会输出 两个 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--);
}
}
------解决方案--------------------一个鸡蛋四只手,每只手的任务都是去握住鸡蛋然后放开。
sale方法就是那个鸡蛋,四个线程就是四只手;
一只手先握住了鸡蛋(获得对象锁),停顿了N毫秒(保持锁)(其他线程等待这个线程释放锁),然后放开(释放锁)。这时鸡蛋没锁,4只手都可以去握(申请对象锁),但总有一只手会先握到(获得锁)
但那只手能握到(哪个线程先获得锁)是不确定的,他是由调度算法来调度的,这就可能出现一种情况,一直是同一只手握到。
你的代码1和代码2区别仅仅在于每次握住要握多久,其他无差别
------解决方案--------------------1、你理解的没错,Thread.sleep(10)这个确实没用
2、你锁定的是sale()方法,只有当你退出这个方法是才会解锁;因为你是多个线程同时执行这个同步方法,理论上是当你解锁时,所有线程都有机会获得这把锁,但最终是哪个线程获得,这个是系统决定的,每次执行都可能不一样。这个不是你能控制的。