1、两个线程同时访问一个对象的同步方法
2、两个线程访问的是两个对象的同步方法
3、两个线程访问的是synchronized的静态方法
4、同时访问同步方法(synchronized修饰)和非同步方法(没有被synchronized修饰)
5、访问同一个对象的不同的普通同步方法(非静态方法)
6、同时访问静态synchronized和非静态synchronized方法
7、方法抛异常后,会释放锁
具体解释:
1、两个线程同时访问一个对象的同步方法
一个一个运行
public class SynchronizedObjectMethod implements Runnable{
static SynchronizedObjectMethod instance = new SynchronizedObjectMethod();
@Override
public void run() {
method();
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
public synchronized void method(){
System.out.println("我的对象锁的方法修饰符形式,我叫:"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
}
2、两个线程访问的是两个对象的同步方法
同时运行
public class SynchronizedObjectCodeBlock implements Runnable {
static SynchronizedObjectCodeBlock instance1 = new SynchronizedObjectCodeBlock();
static SynchronizedObjectCodeBlock instance2 = new SynchronizedObjectCodeBlock();
@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() + "运行结束。");
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
}
3、两个线程访问的是synchronized的静态方法
一个一个运行
public class SynchronizedClassStatic implements Runnable{
static SynchronizedClassStatic instance1 = new SynchronizedClassStatic();
static SynchronizedClassStatic instance2 = new SynchronizedClassStatic();
@Override
public void run() {
method();
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
public static synchronized void method(){
System.out.println("我是类锁的第一种形式:static形式,我叫:"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
}
4、同时访问同步方法(synchronized修饰)和非同步方法(没有被synchronized修饰)
非同步方法不受到影响
public class SynchronizedYesAndNo implements Runnable {
static SynchronizedYesAndNo instance = new SynchronizedYesAndNo();
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")){
method1();
}else {
method2();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
public synchronized void method1() {
System.out.println("我是加锁的方法,我叫:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
public void method2() {
System.out.println("我是没加锁的方法,我叫:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
}
5、访问同一个对象的不同的普通同步方法(非静态方法)
一个一个运行
public class SynchronizedYesAndNo implements Runnable {
static SynchronizedYesAndNo instance = new SynchronizedYesAndNo();
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")){
method1();
}else {
method2();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
public synchronized void method1() {
System.out.println("我是加锁的方法1,我叫:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
public synchronized void method2() {
System.out.println("我是加锁的方法2,我叫:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
}
6、同时访问静态synchronized和非静态synchronized方法
同时运行
public class SynchronizedYesAndNo implements Runnable {
static SynchronizedYesAndNo instance = new SynchronizedYesAndNo();
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")){
method1();
}else {
method2();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
public synchronized static void method1() {
System.out.println("我是静态加锁的方法1,我叫:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
public synchronized void method2() {
System.out.println("我是非静态加锁的方法2,我叫:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
}
7、方法抛异常后,会释放锁
抛出异常后,JVM会释放锁
public class SynchronizedYesAndNo implements Runnable {
static SynchronizedYesAndNo instance = new SynchronizedYesAndNo();
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")){
method1();
}else {
method2();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
public synchronized void method1() {
System.out.println("我是方法1,我叫:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
throw new RuntimeException();
// System.out.println(Thread.currentThread().getName() + "运行结束。");
}
public synchronized void method2() {
System.out.println("我是方法2,我叫:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束。");
}
}