文章目录
- 1 多线程访问同步方法
- 1.1 两个线程同时访问一个对象的同步方法
-
- 1.2 两个线程访问的是两个对象的同步方法
-
- 1.3 两个线程访问的是synchronized的静态方法
-
- 1.4 同时访问同步方法与非同步方法
-
- 1.5 访问同一个对象的不同的普通同步方法
-
- 1.6 同时访问静态synchronized和非静态synchronized方法
-
- 1.7 方法抛出异常后,会释放锁
-
- 2 核心思想
1 多线程访问同步方法
1.1 两个线程同时访问一个对象的同步方法
1.1.1 代码演示
package com.wpj;
public class SynchronizedTest1 implements Runnable {
static SynchronizedTest1 instance = new SynchronizedTest1();
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("finished");
}
@Override
public void run() {
method();
}
private synchronized void method() {
System.out.println("运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("运行结束 " + Thread.currentThread().getName());
}
}
1.1.2 运行结果
运行中 Thread-0
运行结束 Thread-0
运行中 Thread-1
运行结束 Thread-1
finished
1.2 两个线程访问的是两个对象的同步方法
1.2.1 代码演示
package com.wpj;
public class SynchronizedTest2 implements Runnable {
static SynchronizedTest2 instance1 = new SynchronizedTest2();
static SynchronizedTest2 instance2 = new SynchronizedTest2();
public static void main(String[] args) {
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
@Override
public void run() {
synchronized (this) {
System.out.println("运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("运行结束 " + Thread.currentThread().getName());
}
}
}
1.2.2 运行结果
运行中 Thread-0
运行中 Thread-1
运行结束 Thread-0
运行结束 Thread-1
finished
1.3 两个线程访问的是synchronized的静态方法
1.3.1 代码演示
package com.wpj;
public class SynchronizedTest3 implements Runnable {
static SynchronizedTest3 instance1 = new SynchronizedTest3();
static SynchronizedTest3 instance2 = new SynchronizedTest3();
public static void main(String[] args) {
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
@Override
public void run() {
method();
}
private static synchronized void method() {
System.out.println("运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("运行结束 " + Thread.currentThread().getName());
}
}
1.3.2 运行结果
运行中 Thread-0
运行结束 Thread-0
运行中 Thread-1
运行结束 Thread-1
finished
1.4 同时访问同步方法与非同步方法
1.4.1 代码演示
package com.wpj;
public class SynchronizedTest4 implements Runnable {
static SynchronizedTest4 instance = new SynchronizedTest4();
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("finished");
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
private synchronized void method1() {
System.out.println("加锁方法运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("加锁方法运行结束 " + Thread.currentThread().getName());
}
private void method2() {
System.out.println("没加锁方法运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("没加锁方法运行结束 " + Thread.currentThread().getName());
}
}
1.4.2 运行结果
没加锁方法运行中 Thread-1
加锁方法运行中 Thread-0
没加锁方法运行结束 Thread-1
加锁方法运行结束 Thread-0
finished
1.5 访问同一个对象的不同的普通同步方法
1.5.1 代码演示
package com.wpj;
public class SynchronizedTest5 implements Runnable {
static SynchronizedTest5 instance = new SynchronizedTest5();
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("finished");
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
private synchronized void method1() {
System.out.println("加锁方法运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("加锁方法运行结束 " + Thread.currentThread().getName());
}
private synchronized void method2() {
System.out.println("加锁方法运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("加锁方法运行结束 " + Thread.currentThread().getName());
}
}
1.5.2 运行结果
加锁方法运行中 Thread-0
加锁方法运行结束 Thread-0
加锁方法运行中 Thread-1
加锁方法运行结束 Thread-1
finished
1.6 同时访问静态synchronized和非静态synchronized方法
1.6.1 代码演示
package com.wpj;
public class SynchronizedTest6 implements Runnable {
static SynchronizedTest6 instance = new SynchronizedTest6();
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("finished");
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
private static synchronized void method1() {
System.out.println("静态加锁方法运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("静态加锁方法运行结束 " + Thread.currentThread().getName());
}
private synchronized void method2() {
System.out.println("非静态加锁方法运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("非静态加锁方法运行结束 " + Thread.currentThread().getName());
}
}
1.6.2 运行结果
非静态加锁方法运行中 Thread-1
静态加锁方法运行中 Thread-0
非静态加锁方法运行结束 Thread-1
静态加锁方法运行结束 Thread-0
finished
1.7 方法抛出异常后,会释放锁
1.7.1 代码演示
package com.wpj;
public class SynchronizedTest7 implements Runnable {
static SynchronizedTest7 instance = new SynchronizedTest7();
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("finished");
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
private synchronized void method1() {
System.out.println("异常加锁方法运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
throw new RuntimeException();
}
private synchronized void method2() {
System.out.println("加锁方法运行中 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("加锁方法运行结束 " + Thread.currentThread().getName());
}
}
1.7.2 运行结果
异常加锁方法运行中 Thread-0
Exception in thread "Thread-0" java.lang.RuntimeException
at com.wpj.SynchronizedTest7.method1(SynchronizedTest7.java:38)
at com.wpj.SynchronizedTest7.run(SynchronizedTest7.java:24)
at java.lang.Thread.run(Thread.java:748)
加锁方法运行中 Thread-1
加锁方法运行结束 Thread-1
finished
2 核心思想
- 一把锁只能同时被一个线程所获取,没有拿到锁的线程必须等待。 对应 1,5
- 每个实例都对应自己一把锁,不同实例之间互不影响。例外:如果锁对象时*.class或synchronized修饰的静态方法的时候。所有对象共用一把锁。 对应 2,3,4,6
- 无论方法正常执行完毕或者抛出异常都会释放锁。对应 7
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)