synchronized
synchronized修饰实例方法时占用this对象锁;
synchronized修饰静态实例方法时占用类锁(类锁只有一个);
关于synchronized的经典面试题,问题:线程t2执行时是否需要等待线程t1的结束?
首先定义一个类MyThread继承Thread,四个面试题这部分都一样。
class MyThread extends Thread{
private DoThing doThing;
public MyThread(DoThing doThing){
this.doThing = doThing;
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("t1")) {
try {
doThing.doSame();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(Thread.currentThread().getName().equals("t2")) {
try {
doThing.doOther();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
exam01
问: doOther运行是否需要等doSame的结束?
否 因为doOther没有synchronized,所以doOther不需要等待被doSame占用的锁
//问: doOther运行是否需要等doSame的结束?
//否 因为doOther没有synchronized,所以doOther不需要等待被doSame占用的锁
public class Exam01 {
public static void main(String[] args) throws InterruptedException {
DoThing doThing = new DoThing();
Thread t1 = new MyThread(doThing);
Thread t2 = new MyThread(doThing);
t1.setName("t1");
t2.setName("t2");
t1.start();
Thread.sleep(1000); //只是为了保证t1先运行
t2.start();
}
}
class DoThing{
public synchronized void doSame() throws InterruptedException {
System.out.println("doSame begin" + "--->" + Thread.currentThread().getName());
Thread.sleep(1000 * 3);
System.out.println("doSame over" + "--->" + Thread.currentThread().getName());
}
public void doOther() throws InterruptedException{
System.out.println("doOther begin" +"--->" + Thread.currentThread().getName());
System.out.println("doOther over" + "--->" + Thread.currentThread().getName());
}
}
exam02
//问: doOther运行是否需要等doSame的结束?
//是 因为doOther有synchronized,所以doOther需要等待被doSame占用的锁
//问: doOther运行是否需要等doSame的结束?
//是 因为doOther有synchronized,所以doOther需要等待被doSame占用的锁
public class Exam02 {
public static void main(String[] args) throws InterruptedException {
DoThing doThing = new DoThing();
Thread t1 = new MyThread(doThing);
Thread t2 = new MyThread(doThing);
t1.setName("t1");
t2.setName("t2");
t1.start();
Thread.sleep(1000); //只是为了保证t1先运行
t2.start();
}
}
class DoThing{
public synchronized void doSame() throws InterruptedException {
System.out.println("doSame begin" + "--->" + Thread.currentThread().getName());
Thread.sleep(1000 * 3);
System.out.println("doSame over" + "--->" + Thread.currentThread().getName());
}
public synchronized void doOther() throws InterruptedException{
System.out.println("doOther begin" +"--->" + Thread.currentThread().getName());
System.out.println("doOther over" + "--->" + Thread.currentThread().getName());
}
}
exam03
//问: doOther运行是否需要等doSame的结束?
//否 因为MyThread传入的是两个对象,所以t1与t2占用的是两把不同对象的锁,不需要等待
//问: doOther运行是否需要等doSame的结束?
//否 因为MyThread传入的是两个对象,所以t1与t2占用的是两把不同对象的锁,不需要等待
public class Exam03 {
public static void main(String[] args) throws InterruptedException {
DoThing doThing1 = new DoThing();
DoThing doThing2 = new DoThing();
Thread t1 = new MyThread(doThing1);
Thread t2 = new MyThread(doThing2);
t1.setName("t1");
t2.setName("t2");
t1.start();
Thread.sleep(1000); //只是为了保证t1先运行
t2.start();
}
}
class DoThing{
public synchronized void doSame() throws InterruptedException {
System.out.println("doSame begin" + "--->" + Thread.currentThread().getName());
Thread.sleep(1000 * 3);
System.out.println("doSame over" + "--->" + Thread.currentThread().getName());
}
public synchronized void doOther() throws InterruptedException{
System.out.println("doOther begin" +"--->" + Thread.currentThread().getName());
System.out.println("doOther over" + "--->" + Thread.currentThread().getName());
}
}
exam04
//问: doOther运行是否需要等doSame的结束?
//是 因为synchronized修饰的是静态方法,t1占用一个类锁,t2需要等待
//问: doOther运行是否需要等doSame的结束?
//是 因为synchronized修饰的是静态方法,t1占用一个类锁,t2需要等待
public class Exam04 {
public static void main(String[] args) throws InterruptedException {
DoThing doThing1 = new DoThing();
DoThing doThing2 = new DoThing();
Thread t1 = new MyThread(doThing1);
Thread t2 = new MyThread(doThing2);
t1.setName("t1");
t2.setName("t2");
t1.start();
Thread.sleep(1000); //只是为了保证t1先运行
t2.start();
}
}
class DoThing{
public synchronized static void doSame() throws InterruptedException {
System.out.println("doSame begin" + "--->" + Thread.currentThread().getName());
Thread.sleep(1000 * 3);
System.out.println("doSame over" + "--->" + Thread.currentThread().getName());
}
public synchronized static void doOther() throws InterruptedException{
System.out.println("doOther begin" +"--->" + Thread.currentThread().getName());
System.out.println("doOther over" + "--->" + Thread.currentThread().getName());
}
}