概述
- 情况一:两个线程同时访问一个对象的 synchronized 方法,同步执行;
- 情况二:两个线程访问的是两个对象的 synchronized 方法,并行执行;
- 情况三:两个线程同时访问一个 synchronized 静态方法,同步执行;
- 情况四:两个线程同时访问 synchronized 方法与非 synchronized 方法,并发执行;
- 情况五:两个线程同时访问同一个对象的不同 synchronized 方法,同步执行;
- 情况六:两个线程同时访问静态 synchronized 方法和非静态 synchronized 方法,并行执行;
- 情况七:方法抛异常后,会释放锁;
- 情况八:在 synchronized 方法中调用了普通方法,就不是线程安全的了,synchronized 的作用范围只在 “{}” 内;
示例四 - 同时访问同步方法与非同步方法
package com.example.concurrency.example.sync;
public class SynchronizedYesAndNo4 implements Runnable {
static SynchronizedYesAndNo4 instance = new SynchronizedYesAndNo4();
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized void method1() {
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod1() 开始");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod1() 结束");
}
public void method2() {
System.out.println(Thread.currentThread().getName() + " 访问 mothod2() 开始");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 访问 mothod2() 结束");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println(Thread.currentThread().getName() + " 结束");
}
}
输出:
Thread-0 访问 synchronized mothod1() 开始
Thread-1 访问 mothod2() 开始
Thread-0 访问 synchronized mothod1() 结束
Thread-1 访问 mothod2() 结束
main 结束
示例五 - 两个线程同时访问同一个对象的不同 synchronized 方法
package com.example.concurrency.example.sync;
public class SynchronizedYesAndNo5 implements Runnable {
static SynchronizedYesAndNo5 instance = new SynchronizedYesAndNo5();
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized void method1() {
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod1() 开始");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod1() 结束");
}
public synchronized void method2() {
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod2() 开始");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod2() 结束");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println(Thread.currentThread().getName() + " 结束");
}
}
输出:
Thread-0 访问 synchronized mothod1() 开始
Thread-0 访问 synchronized mothod1() 结束
Thread-1 访问 synchronized mothod2() 开始
Thread-1 访问 synchronized mothod2() 结束
main 结束
示例六 - 两个线程同时访问静态 synchronized 方法和非静态 synchronized 方法
package com.example.concurrency.example.sync;
public class SynchronizedYesAndNo6 implements Runnable {
static SynchronizedYesAndNo6 instance = new SynchronizedYesAndNo6();
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized static void method1() {
System.out.println(Thread.currentThread().getName() + " 访问 synchronized static mothod1() 开始");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 访问 synchronized static mothod1() 结束");
}
public synchronized void method2() {
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod2() 开始");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod2() 结束");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println(Thread.currentThread().getName() + " 结束");
}
}
输出:
Thread-1 访问 synchronized mothod2() 开始
Thread-0 访问 synchronized static mothod1() 开始
Thread-1 访问 synchronized mothod2() 结束
Thread-0 访问 synchronized static mothod1() 结束
main 结束
示例七 - 方法抛异常后,会释放锁
package com.example.concurrency.example.sync;
public class SynchronizedYesAndNo7 implements Runnable {
static SynchronizedYesAndNo7 instance = new SynchronizedYesAndNo7();
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized void method1() {
System.out.println(Thread.currentThread().getName() + " 访问 synchronized static mothod1() 开始");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
throw new RuntimeException();
}
public synchronized void method2() {
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod2() 开始");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 访问 synchronized mothod2() 结束");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println(Thread.currentThread().getName() + " 结束");
}
}
输出:
Thread-0 访问 synchronized static mothod1() 开始
Exception in thread "Thread-0" java.lang.RuntimeException
Thread-1 访问 synchronized mothod2() 开始
at com.example.concurrency.example.sync.SynchronizedYesAndNo7.method1(SynchronizedYesAndNo7.java:23)
at com.example.concurrency.example.sync.SynchronizedYesAndNo7.run(SynchronizedYesAndNo7.java:10)
at java.lang.Thread.run(Thread.java:745)
Thread-1 访问 synchronized mothod2() 结束
main 结束