面试7大问题:
1.两个线程同时访问同一个实例的synchronized修饰的方法
2.两个线程分别访问两个不同实例的synchronized修饰的方法
3.两个线程访问的是static synchronized修饰的方法
4.两个线程,一个访问synchronized修饰的方法1,另一个访问没有synchronized修饰的方法2
5.两个线程,一个访问synchronized修饰的方法1,另一个访问synchronized修饰的方法2
6.两个线程,一个访问static synchronized修饰的方法1,另一个访问synchronized修饰的方法2
7.抛出异常后,会自动释放锁
1 2 3相信看过第二节的朋友们都能自己解决。因为第二节都有对应的代码和输出结果。
重点是4567.
4:
public class Test implements Runnable {
static Test instance = new Test();
public static void main(String[] args) {
Thread thread1 = new Thread(instance);
Thread thread2 = new Thread(instance);
thread1.start();
thread2.start();
while (thread1.isAlive() || thread2.isAlive()) {
}
L.p("Test main 函数执行完毕");
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0"))
method1();
else
method2();
}
public synchronized void method1() {
L.p("我叫做" + Thread.currentThread().getName());
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
L.p(Thread.currentThread().getName() + " 执行结束");
}
public void method2() {
L.p("我叫做" + Thread.currentThread().getName());
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
L.p(Thread.currentThread().getName() + " 执行结束");
}
}
输出结果如下(理由见第二节 判断依据):
我叫做Thread-1 // 1 2几乎同时打印,三秒后 3 4 5几乎同时打印
我叫做Thread-0
Thread-1 执行结束
Thread-0 执行结束
Test main 函数执行完毕
5:将上述代码的method2也加上synchronized修饰
输出结果如下:
我叫做Thread-0 // 1 先打印,三秒钟后 2 3几乎同时打印 ,三秒钟后,4 5 几乎同时打印
Thread-0 执行结束
我叫做Thread-1
Thread-1 执行结束
Test main 函数执行完毕
这是因为默认两个synchronized都指向了this锁
6:将method1改为static synchronized修饰
输出结果如下:
我叫做Thread-1 // 1 2几乎同时打印,三秒后 3 4 5几乎同时打印
我叫做Thread-0
Thread-1 执行结束
Thread-0 执行结束
Test main 函数执行完毕
这是因为一个是static修饰的是类锁,一个没有static修饰是对象锁,是不同的锁。
7:
public class Test implements Runnable {
static Test instance = new Test();
public static void main(String[] args) {
Thread thread1 = new Thread(instance);
Thread thread2 = new Thread(instance);
thread1.start();
thread2.start();
while (thread1.isAlive() || thread2.isAlive()) {
}
L.p("Test main 函数执行完毕");
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0"))
method1();
else
method2();
}
public synchronized void method1() {
L.p("我叫做" + Thread.currentThread().getName());
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
throw new RuntimeException();
}
public synchronized void method2() {
L.p("我叫做" + Thread.currentThread().getName());
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
L.p(Thread.currentThread().getName() + " 执行结束");
}
}
输出如下:
我叫做Thread-0 //1先打印,三秒后几乎同时打印2和异常,三秒后,几乎同时打印 3 4
我叫做Thread-1
Exception in thread "Thread-0" java.lang.RuntimeException
at com.eul.server.Test.method1(Test.java:34)
at com.eul.server.Test.run(Test.java:22)
at java.base/java.lang.Thread.run(Unknown Source)
Thread-1 执行结束
Test main 函数执行完毕
说明如果在线程中抛出异常,那么就会释放锁。