Java多线程与并发原理 --- synchronized

快来打我* 2022-02-04 13:59 496阅读 0赞

synchronized

线程安全问题的主要诱因?

1、存在共享数据(也称 临界资源)

2、存在多条线程共同操作这些共享资源

解决问题的根本方法:

同一时刻有且只有一条线程处理这些共享数据,其他线程只有等到改线程处理完,才能对共享数据进行操作。

互斥锁的特性:

互斥性:即是在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程的协调机制。这样在同一时间只有一个线程对需要同步的代码块(复合操作)进行访问。互斥性也被称为操作的原子性。

可见性:必须确保在锁被释放之前,对共享对象所做的修改。对于随后获得该锁的另一个线程是可见的(即在获得锁时,应获得共享变量最新的值),否则另一个线程可能是在本地缓存的某个副本上继续操作。从而引起不一致。

synchronized 锁的不是代码,锁的是对象。

根据获取锁的分类:

一、获取对象锁

获取对象锁的两种方法:

1、同步代码块:(synchronized (this) ,synchronized (类实例对象) ),锁是小括号()中的对象。

2、同步非静态方法:(synchronized method),锁是当前对象的实例对象。

获取类锁

获取类锁的两种用法:

1、同步代码块:(synchronized (类.class) )。锁是小括号()中的类对象

2、同步静态方法:(synchronized static method),锁是当前对象的类对象(Class对象)。

  1. public class SyncThread implements Runnable {
  2. @Override
  3. public void run() {
  4. String threadName = Thread.currentThread().getName();
  5. if (threadName.startsWith(“A”)) {
  6. async();
  7. } else if (threadName.startsWith(“B”)) {
  8. syncObjectBlock1();
  9. } else if (threadName.startsWith(“C”)) {
  10. syncObjectMethod1();
  11. } else if (threadName.startsWith(“D”)) {
  12. syncClassBlock1();
  13. } else if (threadName.startsWith(“E”)) {
  14. syncClassMethod1();
  15. }
  16. }
  17. /**
  18. * 异步方法
  19. */
  20. private void async() {
  21. try {
  22. System.out.println(Thread.currentThread().getName() + “_Async_Start: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  23. Thread.sleep(1000);
  24. System.out.println(Thread.currentThread().getName() + “_Async_End: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. /**
  30. * 方法中有 synchronized(this|object) {} 同步代码块
  31. */
  32. private void syncObjectBlock1() {
  33. System.out.println(Thread.currentThread().getName() + “_SyncObjectBlock1: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  34. synchronized (this) {
  35. try {
  36. System.out.println(Thread.currentThread().getName() + “_SyncObjectBlock1_Start: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  37. Thread.sleep(1000);
  38. System.out.println(Thread.currentThread().getName() + “_SyncObjectBlock1_End: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. /**
  45. * synchronized 修饰非静态方法
  46. */
  47. private synchronized void syncObjectMethod1() {
  48. System.out.println(Thread.currentThread().getName() + “_SyncObjectMethod1: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  49. try {
  50. System.out.println(Thread.currentThread().getName() + “_SyncObjectMethod1_Start: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  51. Thread.sleep(1000);
  52. System.out.println(Thread.currentThread().getName() + “_SyncObjectMethod1_End: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  53. } catch (InterruptedException e) {
  54. e.printStackTrace();
  55. }
  56. }
  57. private void syncClassBlock1() {
  58. System.out.println(Thread.currentThread().getName() + “_SyncClassBlock1: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  59. synchronized (SyncThread.class) {
  60. try {
  61. System.out.println(Thread.currentThread().getName() + “_SyncClassBlock1_Start: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  62. Thread.sleep(1000);
  63. System.out.println(Thread.currentThread().getName() + “_SyncClassBlock1_End: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  64. } catch (InterruptedException e) {
  65. e.printStackTrace();
  66. }
  67. }
  68. }
  69. private synchronized static void syncClassMethod1() {
  70. System.out.println(Thread.currentThread().getName() + “_SyncClassMethod1: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  71. try {
  72. System.out.println(Thread.currentThread().getName() + “_SyncClassMethod1_Start: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  73. Thread.sleep(1000);
  74. System.out.println(Thread.currentThread().getName() + “_SyncClassMethod1_End: “ + new SimpleDateFormat(“HH:mm:ss”).format(new Date()));
  75. } catch (InterruptedException e) {
  76. e.printStackTrace();
  77. }
  78. }
  79. }
  1. public class SyncDemo {
  2. public static void main(String… args) {
  3. SyncThread syncThread = new SyncThread();
  4. Thread A_thread1 = new Thread(syncThread, “A_thread1”);
  5. Thread A_thread2 = new Thread(syncThread, “A_thread2”);
  6. Thread B_thread1 = new Thread(syncThread, “B_thread1”);
  7. Thread B_thread2 = new Thread(syncThread, “B_thread2”);
  8. Thread C_thread1 = new Thread(syncThread, “C_thread1”);
  9. Thread C_thread2 = new Thread(syncThread, “C_thread2”);
  10. Thread D_thread1 = new Thread(syncThread, “D_thread1”);
  11. Thread D_thread2 = new Thread(syncThread, “D_thread2”);
  12. Thread E_thread1 = new Thread(syncThread, “E_thread1”);
  13. Thread E_thread2 = new Thread(syncThread, “E_thread2”);
  14. A_thread1.start();
  15. A_thread2.start();
  16. B_thread1.start();
  17. B_thread2.start();
  18. C_thread1.start();
  19. C_thread2.start();
  20. D_thread1.start();
  21. D_thread2.start();
  22. E_thread1.start();
  23. E_thread2.start();
  24. }
  25. }
  26. watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbmJ1bWk_size_16_color_FFFFFF_t_70

发表评论

表情:
评论列表 (有 0 条评论,496人围观)

还没有评论,来说两句吧...

相关阅读