如何判断锁的是谁?
对象 、Class
深入理解 锁
package com.liu.lock8;
import java.util.concurrent.TimeUnit;
/**
* 8锁 : 关于锁的八个问题
* 1. 标准情况下,两个线程先打印 发短信 还是 打电话 ? 1 发短信!
* 2. sendMessage 延迟4s下 ,还是先发短信
*/
public class Test1 {
public static void main(String[] args) {
Phone phone = new Phone();
// 锁的存在
new Thread(()->{
phone.sendMessage();
},"A").start();
// 延时1s
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone{ // 资源类
// synchronized 锁的是方法的调用对象
// 两个方法用的是同一个锁 谁先拿到谁执行
public synchronized void sendMessage() { // 发短信
// 延时1s
try {
TimeUnit.MILLISECONDS.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发送消息!!");
}
public synchronized void call() { // 打电话
System.out.println("打电话!!");
}
public void hello() { // hello方法没有加同步锁 不是同步方法,不受锁的影响
System.out.println("Hello!");
}
}
package com.liu.lock8;
import java.util.concurrent.TimeUnit;
/**
* 8锁 : 关于锁的八个问题
* 3. 编写了一个普通方法,由线程B调用 此时先打印? Hello => 普通方法不受影响
* 4. 创建两个对象,两个调用者 => 两把锁
*/
public class Test2 {
public static void main(String[] args) {
Phone2 phone = new Phone2();
Phone2 phone2 = new Phone2();
// 锁的存在
new Thread(()->{
phone.sendMessage();
},"A").start();
// 延时1s
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
class Phone2{ // 资源类
// synchronized 锁的是方法的调用对象
// 两个方法用的是同一个锁 谁先拿到谁执行
public synchronized void sendMessage() { // 发短信
// 延时4s
try {
TimeUnit.MILLISECONDS.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发送消息!!");
}
public synchronized void call() { // 打电话
System.out.println("打电话!!");
}
public void hello() { // hello方法没有加同步锁 不是同步方法,不受锁的影响
System.out.println("Hello!");
}
}
package com.liu.lock8;
/**
* 5. 增加两个静态的同步方法 锁的是类Class 模板 先打印发短信
* 6. 两个对象,并且增加两个静态的同步方法? 先打印发短信
*/
import java.util.concurrent.TimeUnit;
public class Test3 {
public static void main(String[] args) {
// 两个对象的Class 模板只有一个!加了static => 锁的是Class
Phone3 phone = new Phone3();
Phone3 phone2 = new Phone3();
// 锁的存在
new Thread(()->{
phone2.sendMessage();
},"A").start();
// 延时1s
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone3{ // 资源类
// synchronized 锁的是方法的调用对象
// static静态方法
// 类一加载就有了! Class模板 锁的是Class
public static synchronized void sendMessage() { // 发短信
// 延时4s
try {
TimeUnit.MILLISECONDS.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发送消息!!");
}
public static synchronized void call() { // 打电话
System.out.println("打电话!!");
}
public void hello() { // hello方法没有加同步锁 不是同步方法,不受锁的影响
System.out.println("Hello!");
}
}
package com.liu.lock8;
import java.util.concurrent.TimeUnit;
/**
* 7. 一个静态同步方法、一个普通同步方法 ,只有一个对象 先打印 打电话
* 8. 一个静态同步方法、一个普通同步方法 ,有两个对象 先打印 打电话
*/
public class Test4 {
public static void main(String[] args) {
// 两个对象的Class 模板只有一个!加了static => 锁的是Class
Phone4 phone = new Phone4();
Phone4 phone2 = new Phone4();
// 锁的存在
new Thread(()->{
phone.sendMessage();
},"A").start();
// 延时1s
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
class Phone4{ // 资源类
// synchronized 锁的是方法的调用对象
// static静态方法
// 类一加载就有了! Class模板 锁的是Class
//静态的同步方法 锁的是Class
public static synchronized void sendMessage() { // 发短信
// 延时4s
try {
TimeUnit.MILLISECONDS.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发送消息!!");
}
// 普通同步方法 锁的是调用者
public synchronized void call() { // 打电话
System.out.println("打电话!!");
}
public void hello() { // hello方法没有加同步锁 不是同步方法,不受锁的影响
System.out.println("Hello!");
}
}
new this 关键字 => 对象锁 具体的 实例 方法的调用对象 多个对象对应多把锁
static 关键字 => 类锁 Class 唯一的一个模板 只有一把锁
原文:https://www.cnblogs.com/liuzhhhao/p/15016269.html