在多线程的使用中,关键字synchronized的使用主要有:1、修饰代码块;2修饰方法。
1、修饰代码块synchronized(obj)
这里主要有synchronized(this)和synchronized(obj),而()中的即为得到的锁,判断锁是否为同一个即判断是否为同步代码块。它的主要判断是锁对象是否相等,对于值类型而言看值是否相同,对于对象类型则看是否为相同的引用,综合而言即为争夺锁的两个obj是否==。
以下是代码实例:
1、synchronized(this):this是当前类的对象实例,所以要判断争夺锁的两个obj是否为同一个对象实例,如果为同一个对象实例,则它们之间互斥。
public class SynchronizedTest implements Runnable{
public void method(){
try {
//这里是同步代码块
synchronized (this){
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000);
}
System.out.println("5秒已结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
method();
}
public static void main(String[] args) {
//争夺锁的两个对象
SynchronizedTest synchronizedTest1 = new SynchronizedTest();
//这里的对象其实是同一个
//1️⃣SynchronizedTest synchronizedTest2 = synchronizedTest1;
//两个不同对象
//2️⃣SynchronizedTest synchronizedTest2 = new SynchronizedTest();
Thread thread1 = new Thread(synchronizedTest1);
Thread thread2 = new Thread(synchronizedTest2);
thread1.start();
thread2.start();
}
}
1️⃣时得到的为
K%SHK8CXN{JOBY2%Y949F_V.png2️⃣时得到的为 KP13Q2L3FZQ3J9}W{UEIM9J.png
synchronized(this)中的this是类的对象实例,在1️⃣中synchronizedTest1创建了一个对象实例,synchronizedTest2只是去引用了这个对象,即为同一个对象,所以它们是同一个锁,会出现互斥现象;而在2️⃣中synchronizedTest2又重新创建了一个新的对象,和synchronizedTest1不是同一个锁,所以不会出现互斥。
2、synchronized(obj):正如开始所说,obj如果是值类型则判断值是否相同,对象则同this,总体而言则是判断调用synchronized的obj在内存中的地址是否相同,如果相同,则是争夺同一把锁。synchronized(SynchronizedTest.class),SynchronizedTest.class的地址相同,线程调用同步代码块都会互斥。
2、修饰方法synchronized
修饰方法主要分为非静态方法和静态方法:
修饰非静态方法就是看类对象是否是同一个,与synchronized(this)相同。
public class SynchronizedTest implements Runnable {
public synchronized void method(){
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("5秒已结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
method();
}
public static void main(String[] args) {
//争夺锁的两个对象
SynchronizedTest synchronizedTest1 = new SynchronizedTest();
//这里的对象其实是同一个
//1️⃣SynchronizedTest synchronizedTest2 = synchronizedTest1;
//两个不同对象
//2️⃣SynchronizedTest synchronizedTest2 = new SynchronizedTest();
Thread thread1 = new Thread(synchronizedTest1);
Thread thread2 = new Thread(synchronizedTest2);
thread1.start();
thread2.start();
}
}
1️⃣时得到的为
3K@71FQK{(F3NB2F@3PX3CO.png
2️⃣时得到的为 1111.png
public class SynchronizedTest implements Runnable {
public static synchronized void method(){
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("5秒已结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
method();
}
public static void main(String[] args) {
//争夺锁的两个对象
SynchronizedTest synchronizedTest1 = new SynchronizedTest();
//这里的对象其实是同一个
//1️⃣SynchronizedTest synchronizedTest2 = synchronizedTest1;
//两个不同对象
//2️⃣SynchronizedTest synchronizedTest2 = new SynchronizedTest();
Thread thread1 = new Thread(synchronizedTest1);
Thread thread2 = new Thread(synchronizedTest2);
thread1.start();
thread2.start();
}
}
修饰静态方法则与SynchronizedTest.class相同。
由此,对于synchronized锁的判断主要是看它们的锁是否是同一个锁,即在内存中的地址是否相同。
修饰非静态方法时,在同一个对象实例中才锁
修饰静态方法时,即同.class
synchronized(obj)根据运行过程中的两个obj是否==来判断是否是同一个锁
网友评论