首页 新闻 会员 周边

Thread.sleep() 的疑问

0
悬赏园豆:20 [已解决问题] 解决于 2019-02-14 12:55

class Run implements Runnable{
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " begin...");
Thread.sleep(1000*20);
System.out.println(Thread.currentThread().getName() + " over...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
public class TestThread {
public static void main(String[] args) {
Run run = new Run();
new Thread(run).start();
new Thread(run).start();
}
}
请问这段代码中 Thread.sleep(1000*20); //线程握住的锁是谁? 是run这个对象?还是谁?

Jinke2017的主页 Jinke2017 | 菜鸟二级 | 园豆:237
提问于:2019-02-13 18:59
< >
分享
最佳答案
1

你的线程类里并没有加锁,所有现在还没有锁的概念

收获园豆:20
让我发会呆 | 老鸟四级 |园豆:2929 | 2019-02-14 10:33

没有加锁 指的是没有显示的 synchronized(xxx){ Thread.sleep(200) ; } 吗?

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 10:58

@Jinke2017: 是的啊

让我发会呆 | 园豆:2929 (老鸟四级) | 2019-02-14 11:02

@让我发会呆:
这是service中的一个方法:
//第一次调用该方法quickAppoint()正常,但是 第二次调用,无法执行quickAppoint(),直到第一次调用方法开的线程 结束, 才能继续第二次的调用。
@Override
public String quickAppoint(String date, String timeSpan, String roomId, String guestId, Integer tagId) throws Exception {
....逻辑代码
//开线程
new Thread(new Runnable() {
@Override
public void run() {
.....
try {
.....
Thread.sleep(end-now);
......
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"mythread").start();
}

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 11:23

quickAppoint()没有加任何的synchronized之类的锁 , 只是单纯想让线程thread1 休眠一定时间后执行。
但 thread1 却堵塞了 下一次的方法调用,我不清楚为什么。

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 11:28

@Jinke2017: 那你应该把调用这个线程方法的类也贴出来啊

让我发会呆 | 园豆:2929 (老鸟四级) | 2019-02-14 11:35

@让我发会呆:
@RequestMapping("/quickAppoint")
@ResponseBody
public Map<String,Object> qucikAppoint(
String date,String timeSpan,String roomId,
String guestId,Integer tagId)
{
Map<String,Object> map = new HashMap<>();
try{
String appointId = adminService.quickAppoint(date,timeSpan,roomId,guestId,tagId);
map.put("status", 1);
map.put("appointId", appointId);
}catch(Exception e){
map.put("status", 0);
}
return map;
}

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 11:38

@Jinke2017: 如果你想让quickAppoint方法休眠一会,你直接在代码里sleep就行了,不需要新启一个线程单独的sleep。
但你说堵塞了下一次的方法调用,是说页面连续请求两次,第二次请求的返回会慢是吗?这个问题我也看不太明白,我觉得每次请求应该互不影响才是啊,因为我觉得新new的线程休眠再久也不会影响当前线程的执行。

让我发会呆 | 园豆:2929 (老鸟四级) | 2019-02-14 11:59

@让我发会呆:
很尴尬,是我调试过程出了问题,两次调用不会有影响的,是我马虎了。谢谢你。

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 12:54

@让我发会呆:
还有一个问题想请教一下,

class Run implements Runnable{
@Override
public void run() {
doit();

}
public synchronized void doit(){
    System.out.println(Thread.currentThread().getName() + " begin...");
    try {
        Thread.sleep(1000*20);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + " over...");
}


public class TestThread {
public static void main(String[] args) throws Exception {
Run run = new Run();
new Thread(run).start();
new Thread(run).start();
}
}
请问doit方法中的Thread.sleep(1000*20); 的锁是谁? 是run对象吗?

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 14:20

@Jinke2017: 因为线程sleep的时候是不会释放之前获取到的锁的,所有当前线程还是持有锁的,这个锁应该是当前类的对象实例,synchronized加在普通方法上和synchronized(this)是一个锁。

让我发会呆 | 园豆:2929 (老鸟四级) | 2019-02-14 14:32

@让我发会呆:
假如我用run这个对象调用一个普通方法,为什么不会受到锁的约束? 不是同一个对象吗?
class Run implements Runnable{
@Override
public void run() {
doit();
}
public synchronized void doit(){
System.out.println(Thread.currentThread().getName() + " begin...");
try {
Thread.sleep(1000*20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " over...");
}
//普通方法
public void doelse(){
System.out.println(Thread.currentThread().getName() + " doelse...");
}
}
public class TestThread {
public static void main(String[] args) throws Exception {
Run run = new Run();
new Thread(run).start();
Thread.sleep(1000);
System.out.println("main..");
run.doelse(); //调用普通方法,使用的依旧是run这个对象,不受锁的约束
}
}

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 14:44

@让我发会呆:
我看了几篇博客,然后试验了一下,
我自己的看法是,[synchronized 且非static ] 方法,锁住的是 所有 [synchronized 且非static] 方法,不知道这样理解对吗?

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 14:52

@Jinke2017: 普通方法当然是不受锁约束的啊。
我上面的意思是,如果你将一个run对象传入线程类中,synchronized(run)和synchronized(this)与synchronized加在普通方法上,它们之间会阻塞的。
《java多线程编程核心技术》《java并发编程的艺术》这些书里的demo可以很好的去理解线程的锁。

让我发会呆 | 园豆:2929 (老鸟四级) | 2019-02-14 15:03

@Jinke2017: 可以这么理解,锁其实就是一把钥匙,你要知道这把钥匙在哪些情况下是唯一的就行了。

让我发会呆 | 园豆:2929 (老鸟四级) | 2019-02-14 15:07

@让我发会呆: 好的,谢谢

Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-18 09:09
其他回答(1)
0

线程握住的锁是谁?
sleep 有锁吗?

czd890 | 园豆:14412 (专家六级) | 2019-02-14 09:26

不明白你的回答。sleep有锁吗? 是什么意思?

支持(0) 反对(0) Jinke2017 | 园豆:237 (菜鸟二级) | 2019-02-14 10:56
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册