请教大虾线程问题,如下代码:
package com.test;
public class Timer {
private static int num = 0;
public synchronized void add(String name) {
num++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "是第" + num + "个访问的用户");
}
package com.test;
public class TestSync implements Runnable {
private Timer t = new Timer();
public void run() {
t.add(Thread.currentThread().getName());
}
package com.test;
public class test {
/**
* @param args
*/
public static void main(String[] args) {
Thread t1=new Thread(new TestSync());
Thread t2=new Thread(new TestSync());
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}
输出的结果一直是:
t1是第2个访问的用户
t2是第2个访问的用户
疑问: 明明已经给 Timer类的add方法加了synchronized, 为么结果都是显示是第2个访问的用户
请求大神指点,小弟在此谢过!
流程分析:首先主线程执行并开启两个线程t1、t2,接下来就是三个线程争抢CPU控制权,假设t1获得控制权,t1线程新建一个timer对象并调用其add方法(这时add方法用的是此timer对象锁,还有忘记说了mun+1),然后t1线程睡眠一秒,其他线程获得控制权,假设t2线程获得控制权,t2线程又创建一个timer对象并调用add方法(此时add方法的锁改为t2timer的锁,mun又加一次1,此时mun为2),接下来自己分析。手打不易不喜勿喷。
这结果没错啊,只可意会不可言传,有两把锁,线程默认使用的是对象锁(你这里有两个timer对象了),将锁改成累级别的锁,即可得到你想要的结果。手打不易不喜勿喷。
public class Timer {
private static int num = 0;
public void add(String name) {
synchronized (Timer.class) { // 类级别锁
num++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "是第" + num + "个访问的用户");
}
}
}
用同一个对象加锁就好了,一般情况少用类锁
TestSync test = new TestSync();
Thread t1=new Thread(test);
Thread t2=new Thread(test);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();