(1)同一个类中的synchronized method m1和method m2互斥吗?
public class T {
public static void main(String[] args){
T t = new T();
new Thread(t::m1,"t1").start();
new Thread(t::m2,"t1").start();
}
// synchronized加在非静态方法上,锁对象即为this
public synchronized void m1(){
System.out.println(Thread.currentThread().getName()+" m1 start.........");
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" m1 end.........");
}
public void m2(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" m2");
}
}
t1线程执行m1方法时要去读this对象锁,但是t2线程并不需要读锁,两者各管各的,没有交集(不共用一把锁)。
(2)同一个类中的synchronized method m1可以调用synchronized method m2吗?
public class T {
public synchronized void m1(){
System.out.println("m1 start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
m2();
}
public synchronized void m2(){
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("m2");
}
}
一个同步方法可以调用另一个同步方法,一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说synchronized获得的锁是可重入的。可以粗浅地理解为同一个线程在已经持有该锁的情况下,可以再次获取锁,并且会在某个状态量上做+1操作。
(3)子类同步方法synchronized method m可以调用父类的synchronized method m吗?
public class T {
synchronized void m(){
System.out.println("m start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("m end");
}
}
class TT extends T{
@Override
synchronized void m(){
System.out.println("child m start");
super.m();
System.out.println("child m end");
}
}
子类对象初始化前,会调用父类构造方法,在结构上相当于包裹了一个父类对象,锁对象都是this,而synchronized又是可重入锁,所以是可以的。
(4)静态同步方法和非静态同步方法互斥吗?
各玩各的,不是同一把锁,谈不上互斥。
(5)带有类锁的方法会影响没有上锁的方法的执行吗?
public class SynchronizedTest {
public static synchronized void test1() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
public void test2() {
int i = 15;
while (i-- > 10) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
public static void main(String[] args) {
final SynchronizedTest myt = new SynchronizedTest();
Thread test1 = new Thread(new Runnable() {
public void run() {
SynchronizedTest.test1();
myt.test2();
}
}, "test1");
Thread test2 = new Thread(new Runnable() {
public void run() {
SynchronizedTest.test1();
myt.test2();
}
}, "test2");
test1.start();
test2.start();
}
}
输出:
test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test1 : 14
test1 : 13
test2 : 3
test1 : 12
test2 : 2
test1 : 11
test2 : 1
test2 : 0
test1 : 10
test2 : 14
test2 : 13
test2 : 12
test2 : 11
test2 : 10
test1有类锁,所以需要thread1执行完thread2才能执行。thread1执行完test1之后,thread2开始执行test1,在这期间,thread1照常执行test2。也就是说:
- 类锁只能在同一时刻被一个对象拥有。
- 当某个方法被类锁锁定的时候,不影响其他对象执行该类中的其他方法。
网友评论