锁
synchronized
synchronized锁的目标
- 对象
public class Test_Sync01 {
Object o = new Object();
public void test() {
synchronized (o) {
System.out.println("o is synchronzied");
}
}
}
- this或者方法体。它们锁的都是当前对象。
public class Test_Sync02 {
public synchronized void test() {
System.out.println("function is start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("function is synchronized");
}
public void testThis() {
synchronized (this) {
System.out.println("this is synchronized");
}
}
public static void main(String[] args) throws InterruptedException {
Test_Sync02 t = new Test_Sync02();
Thread t1 = new Thread( () -> t.test());t
Thread t2 = new Thread( () -> t.testThis());
t1.start();
t2.start();
}
}
- 静态方法体或者XXX.class。它们锁的的都是加载的CLASS对象
public class Test_Sync03 {
public static synchronized void test() {
System.out.println("static function is start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("static function is synchronized");
}t
public void testClass() {
synchronized (Test_Sync03.class) {
System.out.println("class is synchronized");
}
}
public static void main(String[] args) throws InterruptedException {
Test_Sync03 t = new Test_Sync03();
Thread t1 = new Thread( () -> test());
Thread t2 = new Thread( () -> t.testClass());
t1.start();
t2.start();
}
}
- synchronized的锁对象不能是String字符串和Integer、Long等基本数据类型\
锁定方法和非锁定方法可否同时调用?
答:能。
public class Test_Sync04 {
public static synchronized void test() {
System.out.println("function is start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("function is synchronized");
}
public void withoutSync() {
System.out.println("this is not synchronized");
}
public static void main(String[] args) throws InterruptedException {
Test_Sync04 t = new Test_Sync04();
Thread t1 = new Thread( () -> test());
Thread t2 = new Thread( () -> t.withoutSync());
t1.start();
t2.start();
}
}
锁定方法可否重入?
答:能。
public class Test_Sync05 {
public synchronized void test() {
System.out.println("function is start");
againIn();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("function is synchronized");
}
public synchronized void againIn() {
System.out.println("this is synchronized");
}
public static void main(String[] args) throws InterruptedException {
Test_Sync05 t = new Test_Sync05();
Thread t1 = new Thread( () -> t.test());
t1.start();
}
}
synchronized锁的四种状态
- 无锁
- 偏向锁
- 自旋锁(轻量级锁)
- 重量级锁
锁升级的过程
一开始处于无锁状态,当第一个线程获得锁时并且没有其他线程竞争时,连CAS操作都没有做,直接偏向了该线程,如果在接下来的执行过程中,该锁一直没有被其他的线程获取,则持有偏向锁的线程永远不需要再进行同步。当有其他线程竞争时,锁会升级成自旋锁,等待线程在内存中自旋等待,10次以后,如果没有拿到锁,则进入等待队列,由操作系统升级成重量级锁。