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这个对象?还是谁?
你的线程类里并没有加锁,所有现在还没有锁的概念
没有加锁 指的是没有显示的 synchronized(xxx){ Thread.sleep(200) ; } 吗?
@Jinke2017: 是的啊
@让我发会呆:
这是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();
}
quickAppoint()没有加任何的synchronized之类的锁 , 只是单纯想让线程thread1 休眠一定时间后执行。
但 thread1 却堵塞了 下一次的方法调用,我不清楚为什么。
@Jinke2017: 那你应该把调用这个线程方法的类也贴出来啊
@让我发会呆:
@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: 如果你想让quickAppoint方法休眠一会,你直接在代码里sleep就行了,不需要新启一个线程单独的sleep。
但你说堵塞了下一次的方法调用,是说页面连续请求两次,第二次请求的返回会慢是吗?这个问题我也看不太明白,我觉得每次请求应该互不影响才是啊,因为我觉得新new的线程休眠再久也不会影响当前线程的执行。
@让我发会呆:
很尴尬,是我调试过程出了问题,两次调用不会有影响的,是我马虎了。谢谢你。
@让我发会呆:
还有一个问题想请教一下,
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: 因为线程sleep的时候是不会释放之前获取到的锁的,所有当前线程还是持有锁的,这个锁应该是当前类的对象实例,synchronized加在普通方法上和synchronized(this)是一个锁。
@让我发会呆:
假如我用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这个对象,不受锁的约束
}
}
@让我发会呆:
我看了几篇博客,然后试验了一下,
我自己的看法是,[synchronized 且非static ] 方法,锁住的是 所有 [synchronized 且非static] 方法,不知道这样理解对吗?
@Jinke2017: 普通方法当然是不受锁约束的啊。
我上面的意思是,如果你将一个run对象传入线程类中,synchronized(run)和synchronized(this)与synchronized加在普通方法上,它们之间会阻塞的。
《java多线程编程核心技术》《java并发编程的艺术》这些书里的demo可以很好的去理解线程的锁。
@Jinke2017: 可以这么理解,锁其实就是一把钥匙,你要知道这把钥匙在哪些情况下是唯一的就行了。
@让我发会呆: 好的,谢谢
线程握住的锁是谁?
sleep 有锁吗?
不明白你的回答。sleep有锁吗? 是什么意思?