8锁现象
synchronized锁定的到底是什么?
https://www.zhihu.com/question/57794716
如何判断锁的是谁;永远知道他是什么锁,锁到底锁的是谁。
深刻理解我们的锁
1:标准情况下,两个方法,同时加锁,一个对象;
2: 给延迟时间,看哪一个先执行
package com.baidu.Lock8;
/**
* 关于所得8个问题=
* 1:标准情况下,答:1、发短息 2、打电话
* 1 结果:多个线程使用同一个对象,多个线程就是使用一把锁,先调用的先执行!
*
* 2:给sendSms延迟4 秒执行,答:1、发短息 2、打电话
* 2 结果:多个线程使用同一个对象,多个线程就是使用一把锁,先调用的先执行,即使在某方法中设置了阻塞。
*
*
*/
import java.util.concurrent.TimeUnit;
public class Test1 {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(()->{
phone.sendSms();
},"A").start();
//休息一秒;
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone{
//synchronized 锁的对象是 方法的调用者。
//两个方法,用的是同一个锁,谁先拿到是谁执行
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
3:添加一个普通的对象;(不加锁)
4:两个对象,两个同步方法,谁先执行;
package com.baidu.Lock8;
/**
* 3:增加一个普通的方法(没有加锁,): 答:1、hello 2、发短信;
* 结果:多个线程,有的线程有锁,有的线程没锁,两者之间不存在竞争同一把锁的情况,先后执行顺序是随机的。
*
* 4:两个对象,两个同步方法,执行? 答:1、打电话 2、发短息
* 结果:1、被 synchronized 修饰的方法,锁的对象是方法的调用者;
* 2、调用者不同,它们之间用的不是同一个锁,相互之间没有关系
*/
import java.util.concurrent.TimeUnit;
public class Test2 {
public static void main(String[] args) {
//两个对象,两个调用者,两把锁
Phone2 phone1 = new Phone2();
Phone2 phone2 = new Phone2();
// new Thread(()->{
// phone1.hello();
// }).start();
new Thread(()->{
phone1.sendSms();
},"A").start();
//休息一秒;
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
class Phone2{
//synchronized 锁的对象是 方法的调用者。
//两个方法,用的是同一个锁,谁先拿到是谁执行
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
//这里没有锁,不是同步的方法。不受所得影响。
public void hello(){
System.out.println("hello");
}
}
5:添加两个静态的同步方法,只有一个对象
6:两个对象,添加两个静态的同步方法。
package com.baidu.Lock8;
/**
* 5:增加两个静态的同步方法;只有一个对象: 答:1、发短息 2、打电话
* * 被 synchronized 和 static 同时修饰的方法,锁的对象是类的 class 对象,是唯一的一把锁。线程之间是顺序执行。
* * 锁Class和锁对象的区别:
* *
* * 1、Class 锁 ,类模版,只有一个;
* * 2、对象锁 , 通过类模板可以new 多个对象。
*
*
*
* 6:增加两个静态的同步方法;两个对象 答:1、发短息 2、打电话
* * 被 synchronized 修饰 和 static 修饰的方法,锁的对象是类的 class 对象,是唯一的一把锁。
* * Class锁是唯一的,所以多个对象使用的也是同一个Class锁。
*
*
*/
import java.util.concurrent.TimeUnit;
public class Test3 {
public static void main(String[] args) {
//两个对象的Class类模板只有一个,static ,所得是Class对象;
Phone3 phone1 = new Phone3();
Phone3 phone2 = new Phone3();
new Thread(()->{
phone1.sendSms();
},"A").start();
//休息一秒;
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
//
class Phone3{
//synchronized 锁的对象是 方法的调用者。
//static 静态方法;
//类一加载就有了,所得是 Class
public static synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
7:一个静态的同步方法,一个普通的同步方法。一个对象;
8:一个静态的同步方法,一个普通的同步方法。两个对象;
package com.baidu.Lock8;
/**
* 7: 一个静态的同步方法 ,一个普通的同步方法;一个对象;答:1、打电话 2、发信息
* * 被 synchronized和static修饰的方法,锁的对象是类的class对象!唯一的同一把锁;
* * 只被synchronized修饰的方法,是普通锁(如对象锁),不是Class锁,所以进程之间执行顺序互不干扰。
*
*
*
*
* 8: 一个静态的同步方法 ,一个普通的同步方法;两个对象;答:1、打电话 2、发信息
* * 被 synchronized和static修饰的方法,锁的对象是类的class对象!唯一的同一把锁;
* * 只被synchronized修饰的方法,是普通锁(如对象锁),不是Class锁,所以进程之间执行顺序互不干扰。
*
*/
import java.util.concurrent.TimeUnit;
public class Test4 {
public static void main(String[] args) {
Phone4 phone1 = new Phone4();
Phone4 phone2 = new Phone4();
new Thread(()->{
phone1.sendSms();
},"A").start();
//休息一秒;
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
//
class Phone4{
//静态的同步方法
//类一加载就有了,所得是 Class
public static synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
//普通的同步方法
public synchronized void call(){
System.out.println("打电话");
}
}
深入理解:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/71877.html