• 8锁现象详解


    如何判断锁的是谁!理解锁!锁到底锁的是谁!

    对象、class   。

    1.前两个问题

    1. package com.kuang.lock8;
    2. import java.util.concurrent.TimeUnit;
    3. /**
    4. * 8锁 ,就是关于锁的8个问题
    5. * 1、标准情况下,两个线程先打印 发短信还是打电话? 1/发短信 2/打电话
    6. * 2、sendSms 延迟4秒,两个线程先打印 发短信还是 打电话 ? 1/发短信 2/打电话
    7. */
    8. public class Test1 {
    9. public static void main(String[] args) {
    10. Phone phone = new Phone();
    11. //锁的存在,才导致,它先执行。面试的适合,不能说是因为他先被调用,而是它先抢到了锁,所以它先打印!
    12. new Thread(()->{
    13. phone.sendSms();
    14. },"A").start();
    15. try {
    16. TimeUnit.SECONDS.sleep(1);
    17. } catch (InterruptedException e) {
    18. e.printStackTrace();
    19. }
    20. new Thread(()->{
    21. phone.call();
    22. },"B").start();
    23. }
    24. }
    25. class Phone{
    26. //synchronized 锁的对象是方法的调用者! phone
    27. //两个方法用的是同一个锁,谁先拿到谁执行!
    28. public synchronized void sendSms(){
    29. try {
    30. TimeUnit.SECONDS.sleep(4);
    31. } catch (InterruptedException e) {
    32. e.printStackTrace();
    33. }
    34. System.out.println("sendSms");
    35. }
    36. public synchronized void call(){
    37. System.out.println("call");
    38. }
    39. }

    2.3-4问题

    1. package com.kuang.lock8;
    2. import java.util.concurrent.TimeUnit;
    3. /**
    4. * 8锁 ,就是关于锁的8个问题
    5. *
    6. * 3.增加了一个普通方法! 发短信还是Hello? 是hello.
    7. * 4. 两个对象,两个同步方法! 发短信还是打电话? 是打电话
    8. */
    9. public class Test2 {
    10. public static void main(String[] args) {
    11. //两个对象 ,两个调用者 ,两把锁!
    12. Phone2 phone1 = new Phone2();
    13. Phone2 phone2 = new Phone2();
    14. //锁的存在,才导致,它先执行。面试的适合,不能说是因为他先被调用,而是它先抢到了锁,所以它先打印!
    15. new Thread(()->{
    16. phone1.sendSms();
    17. },"A").start();
    18. try {
    19. TimeUnit.SECONDS.sleep(1);
    20. } catch (InterruptedException e) {
    21. e.printStackTrace();
    22. }
    23. new Thread(()->{
    24. phone2.hello();
    25. },"B").start();
    26. }
    27. }
    28. class Phone2{
    29. //synchronized 锁的对象是方法的调用者! phone
    30. //两个方法用的是同一个锁,谁先拿到谁执行!
    31. public synchronized void sendSms(){
    32. try {
    33. TimeUnit.SECONDS.sleep(4);
    34. } catch (InterruptedException e) {
    35. e.printStackTrace();
    36. }
    37. System.out.println("sendSms");
    38. }
    39. public synchronized void call(){
    40. System.out.println("call");
    41. }
    42. //这里没有锁!不是同步方法,不受锁的影响!
    43. public void hello(){
    44. System.out.println("hello");
    45. }
    46. }

    3.5-6

    1. package com.kuang.lock8;
    2. import java.util.concurrent.TimeUnit;
    3. /**
    4. * 8锁 ,就是关于锁的8个问题
    5. *
    6. * 5.增加两个静态同步方法,只有一个对象,先打印,发短信?打电话? 打印发短信!!因为锁的都是同一个class对象
    7. * 6.增加两个对象,两个静态的同步方法,先打印,发短信?打电话? 打印发短信!! 因为锁的都是同一个class对象,与对象本身无关
    8. */
    9. public class Test3 {
    10. public static void main(String[] args) {
    11. //两个对象的class 类模板只有一个,static,锁的是class
    12. Phone3 phone1 = new Phone3();
    13. Phone3 phone2 = new Phone3();
    14. //锁的存在,才导致,它先执行。面试的适合,不能说是因为他先被调用,而是它先抢到了锁,所以它先打印!
    15. new Thread(()->{
    16. phone1.sendSms();
    17. },"A").start();
    18. try {
    19. TimeUnit.SECONDS.sleep(1);
    20. } catch (InterruptedException e) {
    21. e.printStackTrace();
    22. }
    23. new Thread(()->{
    24. phone2.call();
    25. },"B").start();
    26. }
    27. }
    28. //Phone3唯一的一个Class对象
    29. class Phone3{
    30. //synchronized 锁的对象是方法的调用者! phone
    31. //两个方法用的是同一个锁,谁先拿到谁执行!
    32. //static 静态方法
    33. //类一加载就有了!锁的Class 锁的是模板
    34. public static synchronized void sendSms(){
    35. try {
    36. TimeUnit.SECONDS.sleep(4);
    37. } catch (InterruptedException e) {
    38. e.printStackTrace();
    39. }
    40. System.out.println("sendSms");
    41. }
    42. public static synchronized void call(){
    43. System.out.println("call");
    44. }
    45. }

    4.第7个问题

    1. package com.kuang.lock8;
    2. import java.util.concurrent.TimeUnit;
    3. /**
    4. * 8锁 ,就是关于锁的8个问题
    5. *
    6. * 7. 1个静态的同步方法,1个普通的同步方法,1个对象 ,先打印发短信?还是打电话? 打电话,因为锁的不是同一个东西,而打电话的睡眠时间少,所以打电话先打印
    7. *
    8. */
    9. public class Test4 {
    10. public static void main(String[] args) {
    11. //两个对象的class 类模板只有一个,static,锁的是class
    12. Phone4 phone = new Phone4();
    13. //锁的存在,才导致,它先执行。面试的适合,不能说是因为他先被调用,而是它先抢到了锁,所以它先打印!
    14. new Thread(()->{
    15. phone.sendSms();
    16. },"A").start();
    17. try {
    18. TimeUnit.SECONDS.sleep(1);
    19. } catch (InterruptedException e) {
    20. e.printStackTrace();
    21. }
    22. new Thread(()->{
    23. phone.call();
    24. },"B").start();
    25. }
    26. }
    27. //Phone3唯一的一个Class对象
    28. class Phone4{
    29. //静态的同步方法
    30. public static synchronized void sendSms(){
    31. try {
    32. TimeUnit.SECONDS.sleep(4);
    33. } catch (InterruptedException e) {
    34. e.printStackTrace();
    35. }
    36. System.out.println("sendSms");
    37. }
    38. //普通的同步方法
    39. public synchronized void call(){
    40. System.out.println("call");
    41. }
    42. }

    5.8-9个问题

    1. package com.kuang.lock8;
    2. import java.util.concurrent.TimeUnit;
    3. /**
    4. * 8锁 ,就是关于锁的8个问题
    5. *
    6. * 8. 1个静态的同步方法,1个普通的同步方法,2个对象 ,先打印发短信?还是打电话? 打电话,因为锁的不是同一个东西,而打电话的睡眠时间少,所以打电话先打印
    7. * 9. 如何让静态方法与 普通方法实现同步,用 synchronized 在普通方法里 锁住 字节码对象,就可以实现同步 然后就是发短信先打印了
    8. *
    9. */
    10. public class Test5 {
    11. public static void main(String[] args) {
    12. //两个对象的class 类模板只有一个,static,锁的是class
    13. Phone5 phone1 = new Phone5();
    14. Phone5 phone2 = new Phone5();
    15. //锁的存在,才导致,它先执行。面试的时候,不能说是因为他先被调用,而是它先抢到了锁,所以它先打印!
    16. new Thread(()->{
    17. phone1.sendSms();
    18. },"A").start();
    19. try {
    20. TimeUnit.SECONDS.sleep(1);
    21. } catch (InterruptedException e) {
    22. e.printStackTrace();
    23. }
    24. new Thread(()->{
    25. phone2.call();
    26. },"B").start();
    27. }
    28. }
    29. //Phone3唯一的一个Class对象
    30. class Phone5{
    31. //静态的同步方法
    32. public static synchronized void sendSms(){
    33. try {
    34. TimeUnit.SECONDS.sleep(4);
    35. } catch (InterruptedException e) {
    36. e.printStackTrace();
    37. }
    38. System.out.println("sendSms");
    39. }
    40. //普通的同步方法
    41. public void call(){
    42. synchronized(Phone5.class){
    43. System.out.println("call");
    44. }
    45. }
    46. }

    加拓展 

  • 相关阅读:
    C++入门教程(十、联合体)
    【C语言】指针与数组笔试题详解
    el-dialog修改默认内边距el-dialog__body解决方案
    hdfs dfsadmin -safemode无法退出安全模式
    Dockerfile指令与Docker-compose容器编排-搭建docker私有仓库
    qt-C++笔记之按行读取文件并切换复选框打印复选框拼接出的字符串
    docker-compose安装RabbitMQ
    MATLAB | 如何绘制这种带竖线散点的核密度图
    【网站项目】学习资料销售平台 小程序
    论文阅读:SOLOv2: Dynamic, Faster and Stronger
  • 原文地址:https://blog.csdn.net/qq_53374893/article/details/132919058