`
bcyy
  • 浏览: 1859374 次
文章分类
社区版块
存档分类
最新评论

Java多线程之synchronized

 
阅读更多

这里通过三个测试类阐述了synchronized应用的不同场景


首先是最基本的synchronized Method的使用

  1. packagecom.jadyer.thread.sync;
  2. /**
  3. *SynchronizedMethodTest
  4. *@see===================================================================================================
  5. *@see概述:Java中的每个对象都有一个锁(lock)或者叫做监视器(monitor)
  6. *@see说明:当synchronized关键字修饰一个方法时,则该方法为同步方法
  7. *@see当某个线程访问某个对象的synchronized方法时,则表示将该对象上锁
  8. *@see此时其它的任何线程,均无法访问该对象中的任何一个synchronized方法(但允许访问该对象中的非synchronized方法)
  9. *@see直到该线程所访问的synchronized方法执行完毕(或者抛出了异常)之后,该对象的锁才会被释放
  10. *@see此时其它的任何线程,才被允许访问该synchronized方法,或者是该对象中的其它synchronized方法
  11. *@see===================================================================================================
  12. *@see总结:如果一个对象有多个synchronized方法,某一时刻某个线程已经执行了该对象中的某一个synchronized方法
  13. *@see那么在该方法没有执行完毕之前,其它线程是无法访问该对象中的,包括该方法在内的,任何一个synchronized方法
  14. *@see重点在于判断Synchronized锁的是谁。如果该方法是静态的,则锁Class对象,否则锁的就是当前对象
  15. *@see===================================================================================================
  16. *@see补充:1)这只是针对多个线程操作同一个类的同一个对象的情况。www.linuxidc.com若多个线程操作同一个类的不同对象,则不存在这种情况
  17. *@see2)Java中的volatile变量也可以看作是一种"程度较轻的synchronized"
  18. *@see关于volatile的更多信息,请参考http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
  19. *@see备注:实际项目中,用到的更多的还是JDK5.0开始推出的Java并发包,即java.util.concurrent包里面的工具类
  20. *@seejava.util.concurrent可以非常细粒度的实现并发。比如线程访问到了一个已被锁的对象,它可以让这个线程等到10秒
  21. *@see10秒后如果该对象仍未被解锁,那么就可以返回给用户超时的提示等,而如果使用synchronized则是无法这么精确控制的
  22. *@see===================================================================================================
  23. *@see注意:1)当synchronized方法执行完或者发生异常时,会自动释放锁
  24. *@see2)被synchronized保护的数据应该是private的,否则也就没必要去通过方法来访问这个public的数据了
  25. *@see===================================================================================================
  26. *@author宏宇
  27. *@createFeb21,20125:29:39PM
  28. */
  29. publicclassSynchronizedTest{
  30. publicstaticvoidmain(String[]args){
  31. Bankbank=newBank();
  32. Threadtt11=newThread(newThreadRMB(bank));
  33. //new一个新的Bank对象。此时存在两个Bank对象,并且它们属于同一个类的不同的对象
  34. //如要验证多个线程操作同一个类的不同的对象的synchronized方法,只需取消注释该行代码即可
  35. //bank=newBank();
  36. Threadtt22=newThread(newThreadDollar(bank));
  37. tt11.start();
  38. tt22.start();
  39. }
  40. }
  41. classThreadRMBimplementsRunnable{
  42. privateBankbank;
  43. publicThreadRMB(Bankbank){
  44. this.bank=bank;
  45. }
  46. @Override
  47. publicvoidrun(){
  48. bank.getRMB();
  49. }
  50. }
  51. classThreadDollarimplementsRunnable{
  52. privateBankbank;
  53. publicThreadDollar(Bankbank){
  54. this.bank=bank;
  55. }
  56. @Override
  57. publicvoidrun(){
  58. bank.getDollar();
  59. }
  60. }
  61. classBank{
  62. publicsynchronizedvoidgetRMB(){
  63. for(inti=0;i<20;i++){
  64. try{
  65. Thread.sleep((long)(Math.random()*1000));
  66. }catch(InterruptedExceptione){
  67. e.printStackTrace();
  68. }
  69. System.out.println(Thread.currentThread().getName()+":"+i);
  70. }
  71. }
  72. publicsynchronizedvoidgetDollar(){
  73. for(inti=0;i<20;i++){
  74. try{
  75. Thread.sleep((long)(Math.random()*1000));
  76. }catch(InterruptedExceptione){
  77. e.printStackTrace();
  78. }
  79. System.out.println(Thread.currentThread().getName()+":"+i);
  80. }
  81. }
  82. }
下面演示的是synchronized static Method的使用
  1. packagecom.jadyer.thread.sync;
  2. /**
  3. *SynchronizedStaticMethodTest
  4. *@see说明:如果某个synchronized方法是static的
  5. *@see那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是该方法所在的对象所对应的Class对象
  6. *@see因为Java中无论一个类有多少个对象,这些对象都会对应唯一的一个Class对象
  7. *@see因此当线程分别访问同一个类的两个对象的两个static的synchronized方法时,它们的执行顺序也是顺序执行的
  8. *@see即一个线程先执行一个static的synchronized方法,执行完毕后,另一个线程才开始执行另一个static的synchronized方法
  9. *@see总结:重点在于判断synchronized锁的是谁。www.linuxidc.com如果该方法是静态的,则锁Class对象,否则锁的就是当前对象
  10. *@author宏宇
  11. *@createFeb21,20125:29:39PM
  12. */
  13. publicclassSynchronizedStaticTest{
  14. publicstaticvoidmain(String[]args){
  15. Bankbank=newBank();
  16. Threadtt11=newThread(newThreadRMB(bank));
  17. Threadtt22=newThread(newThreadDollar(bank));
  18. tt11.start();
  19. tt22.start();
  20. }
  21. }
  22. classThreadRMBimplementsRunnable{
  23. privateBankbank;
  24. publicThreadRMB(Bankbank){
  25. this.bank=bank;
  26. }
  27. @Override
  28. publicvoidrun(){
  29. bank.getRMB();
  30. }
  31. }
  32. classThreadDollarimplementsRunnable{
  33. privateBankbank;
  34. publicThreadDollar(Bankbank){
  35. this.bank=bank;
  36. }
  37. @Override
  38. publicvoidrun(){
  39. bank.getDollar();
  40. }
  41. }
  42. classBank{
  43. //如要验证synchronized锁同一个类的对象,和锁它的Class对象的区别
  44. //可去掉static关键字,再查看控制台打印,即publicsynchronizedvoidgetRMB()
  45. publicsynchronizedstaticvoidgetRMB(){
  46. for(inti=0;i<20;i++){
  47. try{
  48. Thread.sleep((long)(Math.random()*1000));
  49. }catch(InterruptedExceptione){
  50. e.printStackTrace();
  51. }
  52. System.out.println(Thread.currentThread().getName()+":"+i);
  53. }
  54. }
  55. publicsynchronizedstaticvoidgetDollar(){
  56. for(inti=0;i<20;i++){
  57. try{
  58. Thread.sleep((long)(Math.random()*1000));
  59. }catch(InterruptedExceptione){
  60. e.printStackTrace();
  61. }
  62. System.out.println(Thread.currentThread().getName()+":"+i);
  63. }
  64. }
  65. }
最后演示的是synchronized Block的使用
  1. packagecom.jadyer.thread.sync;
  2. /**
  3. *SynchronizedBlockTest
  4. *@author宏宇
  5. *@createFeb21,20125:29:39PM
  6. */
  7. publicclassSynchronizedBlockTest{
  8. publicstaticvoidmain(String[]args){
  9. Bankbank=newBank();
  10. Threadtt11=newThread(newThreadRMB(bank));
  11. //如果要验证synchronized(this)锁的是当前类的对象,而非当前类的Class对象
  12. //则可取消注释该行代码,再观察控制台打印效果。效果应该是两个线程并发执行的输出
  13. //bank=newBank();
  14. Threadtt22=newThread(newThreadDollar(bank));
  15. tt11.start();
  16. tt22.start();
  17. }
  18. }
  19. classThreadRMBimplementsRunnable{
  20. privateBankbank;
  21. publicThreadRMB(Bankbank){
  22. this.bank=bank;
  23. }
  24. @Override
  25. publicvoidrun(){
  26. bank.getRMB();
  27. }
  28. }
  29. classThreadDollarimplementsRunnable{
  30. privateBankbank;
  31. publicThreadDollar(Bankbank){
  32. this.bank=bank;
  33. }
  34. @Override
  35. publicvoidrun(){
  36. bank.getDollar();
  37. }
  38. }
  39. /**
  40. *Bank
  41. *@see说明:synchronized块的写法:synchronized(object){//TODO...},它表示线程在执行的时候,会对object对象上锁
  42. *@see通常会把java.lang.Object对象传进来,事实上这里可以传进来任何的对象
  43. *@see因为它是一个没有实际作用的对象,其仅仅起到锁的作用,就像一个标识一样
  44. *@see作用:它表示,如果线程能够进入到这里,即执行到这里,那么,就将object对象锁上
  45. *@see如果另一个线程也执行到这里,发现object对象已上锁,则会等待其解锁后,才会去执行synchronized块里面的代码
  46. *@see补充:synchronized(this)表示对当前类的对象上锁。注意,它锁的不是当前类的Class对象
  47. *@seesynchronized(Bank.class)表示对当前类的Class对象上锁
  48. *@author宏宇
  49. *@createFeb22,20122:29:16AM
  50. */
  51. classBank{
  52. privateObjectobj11=newObject();
  53. privateObjectobj22=newObject();
  54. publicvoidgetRMB(){
  55. //synchronized(obj11){
  56. synchronized(Bank.class){
  57. for(inti=0;i<20;i++){
  58. try{
  59. Thread.sleep((long)(Math.random()*1000));
  60. }catch(InterruptedExceptione){
  61. e.printStackTrace();
  62. }
  63. System.out.println(Thread.currentThread().getName()+":"+i);
  64. }
  65. }
  66. }
  67. publicvoidgetDollar(){
  68. //synchronized(obj11){
  69. //synchronized(obj22){
  70. synchronized(this){
  71. for(inti=0;i<20;i++){
  72. try{
  73. Thread.sleep((long)(Math.random()*1000));
  74. }catch(InterruptedExceptione){
  75. e.printStackTrace();
  76. }
  77. System.out.println(Thread.currentThread().getName()+":"+i);
  78. }
  79. }
  80. }
  81. }

分享到:
评论

相关推荐

    java多线程中synchronized关键字的用法

    java多线程中synchronized关键字的用法 解压密码 www.jiangyea.com

    java 多线程synchronized互斥锁demo

    标题中的"java 多线程synchronized互斥锁demo"指的是一个示例,展示了如何在多线程环境下使用`synchronized`关键字创建互斥锁,确保同一时间只有一个线程可以访问特定的代码块或方法。 描述中的"一个多线程访问的同...

    Java多线程(Synchronized+Volatile+JUC 并发工具原理+线程状态+CAS+线程池)

    Java 多线程(Synchronized+Volatile+JUC 并发工具原理+线程状态+CAS+线程池) Java 多线程是 Java 语言中的一种并发编程机制,允许程序同时执行多个线程,以提高程序的执行效率和响应速度。 Java 多线程机制提供了...

    java多线程的讲解和实战

    Java多线程是Java编程中的重要概念,尤其在如今的多核处理器环境下,理解并熟练掌握多线程技术对于提高程序性能和响应速度至关重要。本资料详细讲解了Java多线程的原理,并提供了丰富的实战代码,非常适合Java初学者...

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    java多线程经典案例

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,极大地提升了程序的效率和性能。在Java中,实现多线程有两种主要方式:通过实现Runnable接口或者继承Thread类。本案例将深入探讨Java多线程中的关键...

    java多线程进度条

    本主题将深入探讨如何在Java多线程环境下实现进度条功能。 首先,理解Java多线程的基本概念至关重要。Java通过Thread类和Runnable接口来支持多线程。创建一个新线程通常有两种方式:继承Thread类并重写run()方法,...

    java多线程Demo

    Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新...

    java多线程查询数据库

    综上所述,"java多线程查询数据库"是一个涉及多线程技术、线程池管理、并发控制、分页查询等多个方面的复杂问题。通过理解和掌握这些知识点,我们可以有效地提高数据库操作的效率和系统的响应速度。

    JAVA单线程多线程

    通过以上分析,我们可以看到,在Java中合理利用单线程或多线程以及`synchronized`关键字能够有效地提高程序的性能和响应能力,同时也需要注意其可能带来的复杂性和资源消耗问题。开发者应根据具体的应用场景和需求来...

    JAVA多线程练习题答案。

    JAVA多线程练习题答案详解 在本文中,我们将对 JAVA 多线程练习题的答案进行详细的解释和分析。这些题目涵盖了 JAVA 多线程编程的基本概念和技术,包括线程的生命周期、线程同步、线程状态、线程优先级、线程安全等...

    JAVAJAVA多线程教学演示系统论文

    《JAVA多线程教学演示系统》是一篇深入探讨JAVA多线程编程的论文,它针对教育领域中的教学需求,提供了一种生动、直观的演示方式,帮助学生更好地理解和掌握多线程技术。这篇论文的核心内容可能包括以下几个方面: ...

    java 多线程并发实例

    在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是...

    Java多线程之synchronized&volatile基础篇

    在Java编程语言中,多线程是实现并发执行任务的关键机制。线程是操作系统调度的基本单元,它在进程中运行,负责执行特定的代码序列。在Java中,有多种方式来创建和管理线程。 首先,我们可以继承`Thread`类来创建...

    JAVA多线程编程技术PDF

    这份“JAVA多线程编程技术PDF”是学习和掌握这一领域的经典资料,涵盖了多线程的全部知识点。 首先,多线程的核心概念包括线程的创建与启动。在Java中,可以通过实现Runnable接口或继承Thread类来创建线程。创建后...

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...

    java多线程实现大批量数据导入源码

    本项目以"java多线程实现大批量数据导入源码"为题,旨在通过多线程策略将大量数据切分,并进行并行处理,以提高数据处理速度。 首先,我们需要理解Java中的线程机制。Java通过`Thread`类来创建和管理线程。每个线程...

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...

    Java多线程编程实战指南-核心篇

    《Java多线程编程实战指南-核心篇》是一本深入探讨Java并发编程的书籍,旨在帮助读者掌握在Java环境中创建、管理和同步线程的核心技术。Java的多线程能力是其强大之处,使得开发者能够在同一时间执行多个任务,提高...

    Java多线程练习题

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了系统的效率和响应性。在Java中,多线程的实现主要通过两种方式:继承Thread类和实现Runnable接口。理解并掌握多线程的使用对于任何Java开发者...

Global site tag (gtag.js) - Google Analytics