1.synchronized 修饰方法,同一个对象实例只允许一个线程访问此方法。这是学synchronized 关键字时必须要知道的,那同一个对象实例,synchronized方法在被一个线程访问, 问题1:别的线程同时可以访问其他没有synchronized的方法吗?问题2:可以访问带有synchronized方法吗?
答案:答案1:可以,答案2 :不可以。
解释:当访问synchronized方法是,需要先获取对象锁,因为一个synchronized 方法正在访问,这时对象锁无法获取,所以其他带有synchronized 修饰的方法无法访问, 但是没有synchronized 修饰的方法不需要对象锁,所以可以访问。
光说不行啊,我们要用代码验证一下是吧,上代码:
class SynchronizeTest1 {
public long count1;
public long count2;
public long count3;
public synchronized void printCount1(String threadName) {
for (int j = 0; j < 1000; j++) {
count1++;
}
try {
Thread.sleep(1000l);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("count1:" + count1);
}
public void printCount2(String threadName) {
for (int j = 0; j < 1000; j++) {
count2++;
}
System.out.println("count2:" + count2);
}
public synchronized void printCount3(String threadName) {
for (int j = 0; j < 1000; j++) {
count3++;
}
System.out.println("count3:" + count3);
}
}
public class Test {
public static void main(String[] args) {
SynchronizeTest1 test1 = new SynchronizeTest1();
for (int i = 0; i < 20; i++) {
new Thread(new Runnable() {
@Override
public void run() {
test1.printCount1(Thread.currentThread().getName());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
test1.printCount2(Thread.currentThread().getName());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
test1.printCount3(Thread.currentThread().getName());
}
}).start();
}
}
}
结果:
count2:1000
count2:2484
count2:4000
count2:3000
count2:5000
count2:6000
count2:7000
count2:8000
count2:9000
count2:10000
count2:11000
count2:12000
count2:13000
count2:14000
count2:15000
count2:16000
count2:17134
count2:18000
count2:19000
count2:20000
count1:1000
count1:2000
count1:3000
count1:4000
count3:1000
count1:5000
count1:6000
count1:7000
count1:8000
count1:9000
count3:2000
count3:3000
count3:4000
count1:10000
count3:5000
count1:11000
count1:12000
count3:6000
count3:7000
count3:8000
count3:9000
count1:13000
count1:14000
count1:15000
count3:10000
count3:11000
count3:12000
count1:16000
count3:13000
count3:14000
count3:15000
count1:17000
count1:18000
count3:16000
count1:19000
count1:20000
count3:17000
count3:18000
count3:19000
count3:20000
因为printCount1方法正在占用对象锁,printCount3无法获取对象锁,而printCount2不需要,所以我们看到的结果是count2 先打印完毕,但是count1和count3后来交叉打印.