当前位置:   article > 正文

synchronized 对象锁和类锁的区别详细_synchronized锁类和对象的区别

synchronized锁类和对象的区别

synchronized 是一个关键字。

synchronized 加到 static 方法前面是给class 加锁,即类锁;
synchronized 加到非静态方法上是给对象上锁,即对象锁。

对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同锁的方法时,是异步的。

所以我们用代码来演示下

 

首先准备工作,先创建一个Task类 新建三个方法其中两个 是static修饰静态的。

  1. /**
  2. * @Title: dmdemo
  3. * @Description:
  4. * @author: liaryank
  5. * @Date: 2020/7/23 1:37 下午
  6. * @Version: 1.0
  7. */
  8. public class Task {
  9. public synchronized static void TaskA() {
  10. System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
  11. try {
  12. Thread.sleep(1000);
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");
  17. }
  18. public synchronized static void TaskB() {
  19. System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
  20. try {
  21. Thread.sleep(1000);
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");
  26. }
  27. public synchronized void TaskC() {
  28. System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
  29. try {
  30. Thread.sleep(1000);
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");
  35. }

第二步 创建三个类来调用各自Task中的方法(也就像IG   baolan说:“各过各的”)咱们各调各的。

  1. /**
  2. * @Title: dmdemo
  3. * @Description:
  4. * @author: liaryank
  5. * @Date: 2020/7/23 2:00 下午
  6. * @Version: 1.0
  7. */
  8. public class ThreadA extends Thread{
  9. private Task TTask;
  10. public ThreadA(Task tk){
  11. TTask = tk;
  12. }
  13. public void run() {
  14. TTask.TaskA();
  15. }
  16. }
  17. /**
  18. * @Title: dmdemo
  19. * @Description:
  20. * @author: liaryank
  21. * @Date: 2020/7/23 1:46 下午
  22. * @Version: 1.0
  23. */
  24. public class ThreadB extends Thread{
  25. private Task TTask;
  26. public ThreadB(Task tk){
  27. TTask = tk;
  28. }
  29. public void run() {
  30. TTask.TaskB();
  31. }
  32. }
  33. /**
  34. * @Title: dmdemo
  35. * @Description:
  36. * @author: liaryank
  37. * @Date: 2020/7/23 2:01 下午
  38. * @Version: 1.0
  39. */
  40. public class ThreadC extends Thread{
  41. private Task TTask;
  42. public ThreadC(Task tk){
  43. TTask = tk;
  44. }
  45. public void run() {
  46. TTask.TaskC();
  47. }
  48. }

第三步创建一个main方法咱们来测试一下

  1. public static void main(String[] args) {
  2. Task TTask = new Task();
  3. ThreadA ta = new ThreadA(TTask);
  4. ThreadB tb = new ThreadB(TTask);
  5. ThreadC tc = new ThreadC(TTask);
  6. ta.setName("A");
  7. tb.setName("B");
  8. tc.setName("C");
  9. ta.start();
  10. tb.start();
  11. tc.start();
  12. }

结果如下,我们可以清楚的看到TaskA和TaskB是顺序执行的,而TaskC是和TaskA、TaskB异步执行的。因为TaskA、TaskB是加了static修饰的属于类锁,TaskC是对象锁。

我们来继续测试,测试同步调用TaskC 看看TaskC会不会顺序执行,我们修改ThreadA和ThreadB,让这两个都去调用TaskC方法

 然后咱们main也要改下如下

  1. public static void main(String[] args) {
  2. Task TTaska = new Task();
  3. Task TTaskb = new Task();
  4. ThreadA ta = new ThreadA(TTaska );
  5. ThreadB tb = new ThreadB(TTaskb );
  6. ta.setName("A");
  7. tb.setName("B");
  8. ta.start();
  9. tb.start();
  10. }

 结果如下,可以看出 ThreadA和ThreadB在调用方法锁TaskC时是异步执行的。

 

测试完了方法锁,咱们在试试类锁

将ThreadA和ThreadB中调用方法都改成调用TaskA。mian方法不用变执行即可。

  1. /**
  2. * @Title: dmdemo
  3. * @Description:
  4. * @author: liaryank
  5. * @Date: 2020/7/23 2:00 下午
  6. * @Version: 1.0
  7. */
  8. public class ThreadA extends Thread{
  9. private Task TTask;
  10. public ThreadA(Task tk){
  11. TTask = tk;
  12. }
  13. public void run() {
  14. TTask.TaskA();
  15. }
  16. }
  17. /**
  18. * @Title: dmdemo
  19. * @Description:
  20. * @author: liaryank
  21. * @Date: 2020/7/23 1:46 下午
  22. * @Version: 1.0
  23. */
  24. public class ThreadB extends Thread{
  25. private Task TTask;
  26. public ThreadB(Task tk){
  27. TTask = tk;
  28. }
  29. public void run() {
  30. TTask.TaskA();
  31. }
  32. }

 执行结果如下,从结果我们可以看出,方法上加了静态static 成为类锁后会顺序执行。

我们来小小总结一下:

  1. 类锁对该类的所有对象都能起作用,而对象锁不能。

  2. 多线程访问某类中synchronized修饰的静态和非静态方法时是可以异步执行的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/292059
推荐阅读
相关标签
  

闽ICP备14008679号