synchronized 是java语言关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。

本文直接以代码的形式来展示synchronized 关键字的使用:

【1】synchronized Demo1:

[html] view plain copy
  1. packagecom.andyidea.demo;
  2. /**
  3. *当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,
  4. *一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码
  5. *块以后才能执行该代码块。
  6. *@authorAndy.Chen
  7. *
  8. */
  9. publicclassThread01implementsRunnable{
  10. @Override
  11. publicvoidrun(){
  12. synchronized(this){
  13. for(inti=0;i<3;i++){
  14. System.out.println(Thread.currentThread().getName()+"synchronizedloop"+i);
  15. }
  16. }
  17. }
  18. publicstaticvoidmain(String[]args){
  19. Thread01t01=newThread01();
  20. System.out.println("synchronized关键字使用\n"
  21. +"--------------------------");
  22. Threadta=newThread(t01,"A");
  23. Threadtb=newThread(t01,"B");
  24. ta.start();
  25. tb.start();
  26. }
  27. }

运行结果如下:

[html] view plain copy

  1. synchronized关键字使用
  2. --------------------------
  3. Bsynchronizedloop0
  4. Bsynchronizedloop1
  5. Bsynchronizedloop2
  6. Asynchronizedloop0
  7. Asynchronizedloop1
  8. Asynchronizedloop2

【2】synchronized Demo2:

[html] view plain copy
  1. packagecom.andyidea.demo;
  2. /**
  3. *当一个线程访问object的一个synchronized(this)同步代码块时,
  4. *另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
  5. *@authorAndy.Chen
  6. *
  7. */
  8. publicclassThread02{
  9. publicvoidmethod01(){
  10. synchronized(this){
  11. inti=0;
  12. while(i++<3){
  13. System.out.println(Thread.currentThread().getName()+":"+i);
  14. try{
  15. Thread.sleep(1000);
  16. }catch(InterruptedExceptione){
  17. e.printStackTrace();
  18. }
  19. }
  20. }
  21. }
  22. publicvoidmethod02(){
  23. //第1种方式:当一个线程访问object的一个synchronized(this)同步代码块时,
  24. //另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
  25. //intj=0;
  26. //while(j++<3){
  27. //System.out.println(Thread.currentThread().getName()+":"+j);
  28. //try{
  29. //Thread.sleep(1000);
  30. //}catch(InterruptedExceptione){
  31. //e.printStackTrace();
  32. //}
  33. //}
  34. //第2种方式:当一个线程访问object的一个synchronized(this)同步代码块时,
  35. //其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
  36. synchronized(this){
  37. intj=0;
  38. while(j++<3){
  39. System.out.println(Thread.currentThread().getName()+":"+j);
  40. try{
  41. Thread.sleep(1000);
  42. }catch(InterruptedExceptione){
  43. e.printStackTrace();
  44. }
  45. }
  46. }
  47. }
  48. /**
  49. *当一个线程访问object的一个synchronized(this)同步代码块时,
  50. *它就获得了这个object的对象锁。
  51. *结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
  52. */
  53. publicsynchronizedvoidmethod3(){
  54. intk=0;
  55. while(k++<3){
  56. System.out.println(Thread.currentThread().getName()+":"+k);
  57. try{
  58. Thread.sleep(1000);
  59. }catch(InterruptedExceptione){
  60. e.printStackTrace();
  61. }
  62. }
  63. }
  64. publicstaticvoidmain(String[]args){
  65. finalThread02t02=newThread02();
  66. System.out.println("synchronized关键字使用\n"
  67. +"--------------------------");
  68. Threadt02A=newThread(newRunnable(){
  69. @Override
  70. publicvoidrun(){
  71. t02.method01();
  72. }
  73. },"A");
  74. Threadt02B=newThread(newRunnable(){
  75. @Override
  76. publicvoidrun(){
  77. t02.method02();
  78. }
  79. },"B");
  80. Threadt02C=newThread(newRunnable(){
  81. @Override
  82. publicvoidrun(){
  83. t02.method3();
  84. }
  85. },"C");
  86. t02A.start();
  87. t02B.start();
  88. t02C.start();
  89. }
  90. }
运行结果如下:

[html] view plain copy

  1. synchronized关键字使用
  2. --------------------------
  3. B:1
  4. B:2
  5. B:3
  6. C:1
  7. C:2
  8. C:3
  9. A:1
  10. A:2
  11. A:3


【3】synchronized Demo3:

[html] view plain copy
  1. packagecom.andyidea.demo;
  2. /**
  3. *synchronized对象锁
  4. *@authorAndy.Chen
  5. *
  6. */
  7. publicclassThread03{
  8. classInnerObject{
  9. /**
  10. *内部类方法1
  11. */
  12. privatevoidinnerMethod01(){
  13. inti=0;
  14. while(i++<3){
  15. System.out.println(Thread.currentThread().getName()+":"+i);
  16. try{
  17. Thread.sleep(1000);
  18. }catch(InterruptedExceptione){
  19. e.printStackTrace();
  20. }
  21. }
  22. }
  23. /**
  24. *内部类方法2
  25. */
  26. privatevoidinnerMethod02(){
  27. intj=0;
  28. while(j++<3){
  29. System.out.println(Thread.currentThread().getName()+":"+j);
  30. try{
  31. Thread.sleep(1000);
  32. }catch(InterruptedExceptione){
  33. e.printStackTrace();
  34. }
  35. }
  36. }
  37. }
  38. /**
  39. *外部类方法1
  40. *@paraminnerObj
  41. */
  42. privatevoidouterMethod01(InnerObjectinnerObj){
  43. synchronized(innerObj){
  44. innerObj.innerMethod01();
  45. }
  46. }
  47. /**
  48. *外部类方法2
  49. *@paraminnerObj
  50. */
  51. privatevoidouterMethod02(InnerObjectinnerObj){
  52. innerObj.innerMethod02();
  53. }
  54. publicstaticvoidmain(String[]args){
  55. finalThread03t03=newThread03();
  56. finalInnerObjectinnerObj=t03.newInnerObject();
  57. System.out.println("synchronized关键字使用\n"
  58. +"--------------------------");
  59. Threadt03A=newThread(newRunnable(){
  60. @Override
  61. publicvoidrun(){
  62. t03.outerMethod01(innerObj);
  63. }
  64. },"A");
  65. Threadt03B=newThread(newRunnable(){
  66. @Override
  67. publicvoidrun(){
  68. t03.outerMethod02(innerObj);
  69. }
  70. },"B");
  71. t03A.start();
  72. t03B.start();
  73. }
  74. }
运行结果如下:

[html] view plain copy
  1. synchronized关键字使用
  2. --------------------------
  3. A:1
  4. B:1
  5. B:2
  6. A:2
  7. B:3
  8. A:3

总结:

1. synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。

2.synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。

对synchronized(this)的一些理解
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

四、当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. android中WebView的Java与JavaScript交互
  3. (转)Android(安卓)Studio插件整理
  4. 最全面的安卓ANR
  5. 一行代码完成Android(安卓)7 FileProvider适配~
  6. GIS的学习(二十四)android异步调用geoserver wms中的地图
  7. [Android实例] 基于ffmpeg的Android播放器开源代码
  8. Android(安卓)第九天(下午)
  9. delphi xe5 android 调用照相机获取拍的照片

随机推荐

  1. (亲测有效)Android SDK Manager国内无法
  2. 【android基础】之Android返回键处理(事
  3. Android之XUtils的框架总结
  4. eclipse下android的sdk配置问题
  5. 我是如何自学Android,资料分享(2015 版)
  6. Android中的Shape美化
  7. Android(安卓)TextView文字横向自动滚动(
  8. Android 技术专题系列之三 -- 编译(build)
  9. Android 相对布局:RelativeLayout
  10. Android分区解释:boot, system, recovery,