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