Java多线程之synchronized关键字全面总结(面试7大问题)3.0

面试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 函数执行完毕

说明如果在线程中抛出异常,那么就会释放锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值