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

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

 

  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. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值