synchronized 函数中 Thread.sleep 作用

fbmgua 2012-11-28 04:38:31
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--);
}
}
...全文
311 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zxhcloth 2012-11-28
  • 打赏
  • 举报
回复
引用 3 楼 fbmgua 的回复:
引用 2 楼 zxhcloth 的回复:1、你理解的没错,Thread.sleep(10)这个确实没用 2、你锁定的是sale()方法,只有当你退出这个方法是才会解锁;因为你是多个线程同时执行这个同步方法,理论上是当你解锁时,所有线程都有机会获得这把锁,但最终是哪个线程获得,这个是系统决定的,每次执行都可能不一样。这个不是你能控制的。 如果其他线程有非同步函数的话,在线程没有解锁的时候,可以访问其他线程的非同步函数吗?
可以访问其他线程的非同步函数
fbmgua 2012-11-28
  • 打赏
  • 举报
回复
引用 1 楼 icebamboo_moyun 的回复:
一个鸡蛋四只手,每只手的任务都是去握住鸡蛋然后放开。 sale方法就是那个鸡蛋,四个线程就是四只手; 一只手先握住了鸡蛋(获得对象锁),停顿了N毫秒(保持锁)(其他线程等待这个线程释放锁),然后放开(释放锁)。这时鸡蛋没锁,4只手都可以去握(申请对象锁),但总有一只手会先握到(获得锁) 但那只手能握到(哪个线程先获得锁)是不确定的,他是由调度算法来调度的,这……
如果其他线程有非同步函数的话,在线程没有解锁的时候,可以访问其他线程的非同步函数吗?
fbmgua 2012-11-28
  • 打赏
  • 举报
回复
引用 2 楼 zxhcloth 的回复:
1、你理解的没错,Thread.sleep(10)这个确实没用 2、你锁定的是sale()方法,只有当你退出这个方法是才会解锁;因为你是多个线程同时执行这个同步方法,理论上是当你解锁时,所有线程都有机会获得这把锁,但最终是哪个线程获得,这个是系统决定的,每次执行都可能不一样。这个不是你能控制的。
如果其他线程有非同步函数的话,在线程没有解锁的时候,可以访问其他线程的非同步函数吗?
zxhcloth 2012-11-28
  • 打赏
  • 举报
回复
1、你理解的没错,Thread.sleep(10)这个确实没用 2、你锁定的是sale()方法,只有当你退出这个方法是才会解锁;因为你是多个线程同时执行这个同步方法,理论上是当你解锁时,所有线程都有机会获得这把锁,但最终是哪个线程获得,这个是系统决定的,每次执行都可能不一样。这个不是你能控制的。
惑惑 2012-11-28
  • 打赏
  • 举报
回复
一个鸡蛋四只手,每只手的任务都是去握住鸡蛋然后放开。 sale方法就是那个鸡蛋,四个线程就是四只手; 一只手先握住了鸡蛋(获得对象锁),停顿了N毫秒(保持锁)(其他线程等待这个线程释放锁),然后放开(释放锁)。这时鸡蛋没锁,4只手都可以去握(申请对象锁),但总有一只手会先握到(获得锁) 但那只手能握到(哪个线程先获得锁)是不确定的,他是由调度算法来调度的,这就可能出现一种情况,一直是同一只手握到。 你的代码1和代码2区别仅仅在于每次握住要握多久,其他无差别

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧