JUC
本文参考biibili 狂神说java的视频
- synchronize 的六种锁的情况 详情请看代码里面的注释
第一种
package lock;
import java.util.concurrent.TimeUnit;
/**
* synchronize 锁住两个方法
* 结果先发短信,在打电话
* 原因: 因为synchronize 在方法上,锁住的是对象,你new了几个对象就几个锁
* 那么也就是说现在只有一个锁,而且程序顺序执行,发短信的线程先拿到锁,因为此时不是异常,
* synchronize只有在异常的时候才会释放锁,所以不会释放锁,执行完之后第二个在执行
*/
public class test1 {
public static void main(String[] args) throws InterruptedException {
Phone p = new Phone();
new Thread(() -> {
p.send();
}, "A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
p.call();
}, "B").start();
}
}
class Phone {
public synchronized void send() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void call() {
System.out.println("打电话");
}
}
```
第二种
package lock;
import java.util.concurrent.TimeUnit;
/**
* 还是synchronizie 锁住了两个方法,但是new了两个对象,所以说就有两个锁,那么就会自己管自己的
* 结果是 打电话,发短信
*/
public class test2 {
public static void main(String[] args) throws InterruptedException {
Phone1 p = new Phone1();
Phone1 p2 = new Phone1();
new Thread(() -> {
p.send();
}, "A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
p2.call();
}, "B").start();
}
}
class Phone1 {
public synchronized void send() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void call() {
System.out.println("打电话");
}
}
第三种
package lock;
import java.util.concurrent.TimeUnit;
/**
* 一个被synchronize锁住,一个没锁,所以就是正常执行
* 打电话,发短信
*/
public class test3 {
public static void main(String[] args) throws InterruptedException {
Phone3 p = new Phone3();
new Thread(() -> {
p.send();
}, "A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
p.call();
}, "B").start();
}
}
class Phone3 {
public synchronized void send() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void call() {
System.out.println("打电话");
}
}
第四种
package lock;
import java.util.concurrent.TimeUnit;
/**
* synchronize锁住静态方法
* 发短信,打电话
* synchronize锁住静态方法的时候其实是锁住的Class模板,锁住的是这个类,那么此时就只有一个锁
*/
public class test4 {
public static void main(String[] args) throws InterruptedException {
Phone4 p = new Phone4();
new Thread(() -> {
p.send();
}, "A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
p.call();
}, "B").start();
}
}
class Phone4 {
public static synchronized void send() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void call() {
System.out.println("打电话");
}
}
第五种
package lock;
import java.util.concurrent.TimeUnit;
/**
* synchronize锁住的还是static 但是现在new了两个对象,但是只有一个Class模板。所以说仍然只有一把锁
* 发短信,打电话
*/
public class test5{
public static void main(String[] args) throws InterruptedException {
Phone5 p = new Phone5();
Phone5 p2 = new Phone5();
new Thread(() -> {
p.send();
}, "A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
p2.call();
}, "B").start();
}
}
class Phone5 {
public static synchronized void send() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void call() {
System.out.println("打电话");
}
}
第六种
package lock;
import java.util.concurrent.TimeUnit;
/**
* 一个锁住了static方法,一个锁住了普通方法, 所以说一个锁在了Class 一个锁住了对象,有两把锁
* 打电话,发短信
*/
public class test6{
public static void main(String[] args) throws InterruptedException {
Phone6 p = new Phone6();
new Thread(() -> {
p.send();
}, "A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
p.call();
}, "B").start();
}
}
class Phone6 {
public static synchronized void send() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void call() {
System.out.println("打电话");
}
}