`
weina
  • 浏览: 144891 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

线程的原子性

    博客分类:
  • java
阅读更多
1,关于线程安全,如果一个方法里面全部是局部变量,那么是没有必要同步的,也就是说它是线程安全的。也就是不必加 synchronized,servelet里面的的HttpServlet就是这样,  PrintWriter out = response.getWriter();这句话中这个out流本来可以作为HttpServlet的类变量的,但是如果是那样就需要同步了,影响效率呀。



2,关于锁,
Java代码

   1. class Test{ 
   2.     public synchronized void f1(){ 
   3.     //do something here 
   4.     } 
   5.     public void f2(){ 
   6.     synchronized(this){ 
   7.     //do something here 
   8.     } 
   9.     } 
  10.     } 

class Test{
    public synchronized void f1(){
    //do something here
    }
    public void f2(){
    synchronized(this){
    //do something here
    }
    }
    }





上面的f1()和f2()效果一致, synchronized取得的锁都是Test某个实列(this)的锁.
    比如: Test t = new Test();
    线程A调用t.f2()时, 线程B无法进入t.f1(),直到t.f2()结束.
    作用: 多线程中访问Test的同一个实例的同步方法时会进行同步.
也就是说在f1()前面加上synchronized ,那线程在调用这个方法的时候取得了这个对象的锁,也就是t的锁,



其他的线程想访问t的其他同步方法,比如f2()就不行,其实这样是不好的,很多时候我们用另外实例变量来锁。


Java代码

   1. class Test{ 
   2.  
   3.   private static final Object obj=new Object(); 
   4.     public synchronized void f1(){ 
   5.     //do something here 
   6.     } 
   7.     public void f2(){ 
   8.     synchronized(obj){ 
   9.     //do something here 
  10.     } 
  11.     } 
  12.     } 

class Test{

  private static final Object obj=new Object();
    public synchronized void f1(){
    //do something here
    }
    public void f2(){
    synchronized(obj){
    //do something here
    }
    }
    }

此时,如果一个线程访问f2,它拿到的是obj对象的锁,别的线程依然可以访问f1().



3,原子性,先看代码:


Java代码

   1. package com.test; 
   2.  
   3.  
   4.  
   5. public class Test extends Thread { 
   6.  
   7.   private int a = 0; 
   8.  
   9.   private int b = 0; 
  10.  
  11.   public static void main(String[] args) { 
  12.  
  13.     Test test = new Test(); 
  14.  
  15.     for (int i = 0; i < 10; i++) { 
  16.  
  17.       Thread thread = new Thread(test, "thread-" + i); 
  18.  
  19.       thread.start(); 
  20.  
  21.     } 
  22.  
  23.   } 
  24.  
  25.   public synchronized void doWrite() { 
  26.  
  27.     a++; 
  28.  
  29.     try { 
  30.  
  31.       sleep((int)(Math.random()*100)); 
  32.  
  33.     } 
  34.  
  35.     catch (Exception e) { 
  36.  
  37.     } 
  38.  
  39.     b++; 
  40.  
  41.     try { 
  42.  
  43.        sleep((int)(Math.random()*100)); 
  44.  
  45.     } 
  46.  
  47.     catch (Exception e) { 
  48.  
  49.     } 
  50.  
  51.   } 
  52.  
  53.   public synchronized void print() { 
  54.  
  55.     System.out.println("" + Thread.currentThread().getName() + ":a:" + a); 
  56.  
  57.     System.out.println("" + Thread.currentThread().getName() + ":b:" + b); 
  58.  
  59.   } 
  60.  
  61.   public void run() { 
  62.      f(); 
  63.     
  64.   } 
  65.  
  66.   public   synchronized  void f() { 
  67.     for (int i = 0; i < 5; i++) { 
  68.  
  69.       doWrite(); 
  70.  
  71.       print(); 
  72.  
  73.     } 
  74.   } 
  75.  
  76. } 

package com.test;



public class Test extends Thread {

  private int a = 0;

  private int b = 0;

  public static void main(String[] args) {

    Test test = new Test();

    for (int i = 0; i < 10; i++) {

      Thread thread = new Thread(test, "thread-" + i);

      thread.start();

    }

  }

  public synchronized void doWrite() {

    a++;

    try {

      sleep((int)(Math.random()*100));

    }

    catch (Exception e) {

    }

    b++;

    try {

       sleep((int)(Math.random()*100));

    }

    catch (Exception e) {

    }

  }

  public synchronized void print() {

    System.out.println("" + Thread.currentThread().getName() + ":a:" + a);

    System.out.println("" + Thread.currentThread().getName() + ":b:" + b);

  }

  public void run() {
     f();
  
  }

  public   synchronized  void f() {
    for (int i = 0; i < 5; i++) {

      doWrite();

      print();

    }
  }

}





输出结果:
Java代码

   1. thread-0:a:1 
   2. thread-0:b:1 
   3. thread-0:a:2 
   4. thread-0:b:2 
   5. thread-0:a:3 
   6. thread-0:b:3 
   7. thread-0:a:4 
   8. thread-0:b:4 
   9. thread-0:a:5 
  10. thread-0:b:5 
  11. thread-1:a:6 
  12. thread-1:b:6 
  13. thread-1:a:7 
  14. thread-1:b:7 
  15. thread-1:a:8 
  16. thread-1:b:8 
  17. thread-1:a:9 
  18. thread-1:b:9 
  19. thread-1:a:10 
  20. thread-1:b:10 
  21. thread-2:a:11 
  22. thread-2:b:11 
  23. thread-2:a:12 
  24. thread-2:b:12 
  25. thread-2:a:13 
  26. thread-2:b:13 
  27. thread-2:a:14 
  28. thread-2:b:14 
  29. thread-2:a:15 
  30. thread-2:b:15 
  31. thread-3:a:16 
  32. thread-3:b:16 
  33. thread-3:a:17 
  34. thread-3:b:17 
  35. thread-3:a:18 
  36. thread-3:b:18 
  37. thread-3:a:19 
  38. thread-3:b:19 
  39. thread-3:a:20 
  40. thread-3:b:20 
  41. thread-4:a:21 
  42. thread-4:b:21 
  43. thread-4:a:22 
  44. thread-4:b:22 
  45. thread-4:a:23 
  46. thread-4:b:23 
  47. thread-4:a:24 
  48. thread-4:b:24 
  49. thread-4:a:25 
  50. thread-4:b:25 
  51. thread-5:a:26 
  52. thread-5:b:26 
  53. thread-5:a:27 
  54. thread-5:b:27 
  55. thread-5:a:28 
  56. thread-5:b:28 
  57. thread-5:a:29 
  58. thread-5:b:29 
  59. thread-5:a:30 
  60. thread-5:b:30 
  61. thread-6:a:31 
  62. thread-6:b:31 
  63. thread-6:a:32 
  64. thread-6:b:32 
  65. thread-6:a:33 
  66. thread-6:b:33 
  67. thread-6:a:34 
  68. thread-6:b:34 
  69. thread-6:a:35 
  70. thread-6:b:35 
  71. thread-7:a:36 
  72. thread-7:b:36 
  73. thread-7:a:37 
  74. thread-7:b:37 
  75. thread-7:a:38 
  76. thread-7:b:38 
  77. thread-7:a:39 
  78. thread-7:b:39 
  79. thread-7:a:40 
  80. thread-7:b:40 
  81. thread-8:a:41 
  82. thread-8:b:41 
  83. thread-8:a:42 
  84. thread-8:b:42 
  85. thread-8:a:43 
  86. thread-8:b:43 
  87. thread-8:a:44 
  88. thread-8:b:44 
  89. thread-8:a:45 
  90. thread-8:b:45 
  91. thread-9:a:46 
  92. thread-9:b:46 
  93. thread-9:a:47 
  94. thread-9:b:47 
  95. thread-9:a:48 
  96. thread-9:b:48 
  97. thread-9:a:49 
  98. thread-9:b:49 
  99. thread-9:a:50 
100. thread-9:b:50 

thread-0:a:1
thread-0:b:1
thread-0:a:2
thread-0:b:2
thread-0:a:3
thread-0:b:3
thread-0:a:4
thread-0:b:4
thread-0:a:5
thread-0:b:5
thread-1:a:6
thread-1:b:6
thread-1:a:7
thread-1:b:7
thread-1:a:8
thread-1:b:8
thread-1:a:9
thread-1:b:9
thread-1:a:10
thread-1:b:10
thread-2:a:11
thread-2:b:11
thread-2:a:12
thread-2:b:12
thread-2:a:13
thread-2:b:13
thread-2:a:14
thread-2:b:14
thread-2:a:15
thread-2:b:15
thread-3:a:16
thread-3:b:16
thread-3:a:17
thread-3:b:17
thread-3:a:18
thread-3:b:18
thread-3:a:19
thread-3:b:19
thread-3:a:20
thread-3:b:20
thread-4:a:21
thread-4:b:21
thread-4:a:22
thread-4:b:22
thread-4:a:23
thread-4:b:23
thread-4:a:24
thread-4:b:24
thread-4:a:25
thread-4:b:25
thread-5:a:26
thread-5:b:26
thread-5:a:27
thread-5:b:27
thread-5:a:28
thread-5:b:28
thread-5:a:29
thread-5:b:29
thread-5:a:30
thread-5:b:30
thread-6:a:31
thread-6:b:31
thread-6:a:32
thread-6:b:32
thread-6:a:33
thread-6:b:33
thread-6:a:34
thread-6:b:34
thread-6:a:35
thread-6:b:35
thread-7:a:36
thread-7:b:36
thread-7:a:37
thread-7:b:37
thread-7:a:38
thread-7:b:38
thread-7:a:39
thread-7:b:39
thread-7:a:40
thread-7:b:40
thread-8:a:41
thread-8:b:41
thread-8:a:42
thread-8:b:42
thread-8:a:43
thread-8:b:43
thread-8:a:44
thread-8:b:44
thread-8:a:45
thread-8:b:45
thread-9:a:46
thread-9:b:46
thread-9:a:47
thread-9:b:47
thread-9:a:48
thread-9:b:48
thread-9:a:49
thread-9:b:49
thread-9:a:50
thread-9:b:50

我们可以看到是很标准的输出。



我们在run方法里面改点东西:


Java代码

   1. package com.test; 
   2.  
   3.  
   4.  
   5. public class Test extends Thread { 
   6.  
   7.   private int a = 0; 
   8.  
   9.   private int b = 0; 
  10.  
  11.   public static void main(String[] args) { 
  12.  
  13.     Test test = new Test(); 
  14.  
  15.     for (int i = 0; i < 10; i++) { 
  16.  
  17.       Thread thread = new Thread(test, "thread-" + i); 
  18.  
  19.       thread.start(); 
  20.  
  21.     } 
  22.  
  23.   } 
  24.  
  25.   public synchronized void doWrite() { 
  26.  
  27.     a++; 
  28.  
  29.     try { 
  30.  
  31.       sleep((int)(Math.random()*100)); 
  32.  
  33.     } 
  34.  
  35.     catch (Exception e) { 
  36.  
  37.     } 
  38.  
  39.     b++; 
  40.  
  41.     try { 
  42.  
  43.        sleep((int)(Math.random()*100)); 
  44.  
  45.     } 
  46.  
  47.     catch (Exception e) { 
  48.  
  49.     } 
  50.  
  51.   } 
  52.  
  53.   public synchronized void print() { 
  54.  
  55.     System.out.println("" + Thread.currentThread().getName() + ":a:" + a); 
  56.  
  57.     System.out.println("" + Thread.currentThread().getName() + ":b:" + b); 
  58.  
  59.   } 
  60.  
  61.   public void run() { 
  62.     for (int i = 0; i < 5; i++) { 
  63.  
  64.       doWrite(); 
  65.  
  66.       print(); 
  67.  
  68.     } 
  69.     
  70.   } 
  71.  
  72.    
  73.  
  74. } 

package com.test;



public class Test extends Thread {

  private int a = 0;

  private int b = 0;

  public static void main(String[] args) {

    Test test = new Test();

    for (int i = 0; i < 10; i++) {

      Thread thread = new Thread(test, "thread-" + i);

      thread.start();

    }

  }

  public synchronized void doWrite() {

    a++;

    try {

      sleep((int)(Math.random()*100));

    }

    catch (Exception e) {

    }

    b++;

    try {

       sleep((int)(Math.random()*100));

    }

    catch (Exception e) {

    }

  }

  public synchronized void print() {

    System.out.println("" + Thread.currentThread().getName() + ":a:" + a);

    System.out.println("" + Thread.currentThread().getName() + ":b:" + b);

  }

  public void run() {
    for (int i = 0; i < 5; i++) {

      doWrite();

      print();

    }
  
  }

 

}



输出的结果就不确定了:


Java代码

   1. thread-0:a:10 
   2. thread-0:b:10 
   3. thread-1:a:10 
   4. thread-1:b:10 
   5. thread-2:a:10 
   6. thread-2:b:10 
   7. thread-3:a:10 
   8. thread-3:b:10 
   9. thread-4:a:10 
  10. thread-4:b:10 
  11. thread-5:a:10 
  12. thread-5:b:10 
  13. thread-6:a:10 
  14. thread-6:b:10 
  15. thread-7:a:10 
  16. thread-7:b:10 
  17. thread-8:a:10 
  18. thread-8:b:10 
  19. thread-9:a:10 
  20. thread-9:b:10 
  21. thread-0:a:20 
  22. thread-0:b:20 
  23. thread-1:a:20 
  24. thread-1:b:20 
  25. thread-2:a:20 
  26. thread-2:b:20 
  27. thread-3:a:20 
  28. thread-3:b:20 
  29. thread-4:a:20 
  30. thread-4:b:20 
  31. thread-5:a:20 
  32. thread-5:b:20 
  33. thread-6:a:20 
  34. thread-6:b:20 
  35. thread-7:a:20 
  36. thread-7:b:20 
  37. thread-8:a:20 
  38. thread-8:b:20 
  39. thread-9:a:20 
  40. thread-9:b:20 
  41. thread-0:a:30 
  42. thread-0:b:30 
  43. thread-1:a:30 
  44. thread-1:b:30 
  45. thread-2:a:30 
  46. thread-2:b:30 
  47. thread-3:a:30 
  48. thread-3:b:30 
  49. thread-4:a:30 
  50. thread-4:b:30 
  51. thread-5:a:30 
  52. thread-5:b:30 
  53. thread-6:a:30 
  54. thread-6:b:30 
  55. thread-7:a:30 
  56. thread-7:b:30 
  57. thread-8:a:30 
  58. thread-8:b:30 
  59. thread-9:a:30 
  60. thread-9:b:30 
  61. thread-0:a:40 
  62. thread-0:b:40 
  63. thread-1:a:40 
  64. thread-1:b:40 
  65. thread-2:a:40 
  66. thread-2:b:40 
  67. thread-3:a:40 
  68. thread-3:b:40 
  69. thread-4:a:40 
  70. thread-4:b:40 
  71. thread-5:a:40 
  72. thread-5:b:40 
  73. thread-6:a:40 
  74. thread-6:b:40 
  75. thread-7:a:40 
  76. thread-7:b:40 
  77. thread-8:a:40 
  78. thread-8:b:40 
  79. thread-9:a:40 
  80. thread-9:b:40 
  81. thread-0:a:50 
  82. thread-0:b:50 
  83. thread-1:a:50 
  84. thread-1:b:50 
  85. thread-2:a:50 
  86. thread-2:b:50 
  87. thread-3:a:50 
  88. thread-3:b:50 
  89. thread-4:a:50 
  90. thread-4:b:50 
  91. thread-5:a:50 
  92. thread-5:b:50 
  93. thread-6:a:50 
  94. thread-6:b:50 
  95. thread-7:a:50 
  96. thread-7:b:50 
  97. thread-8:a:50 
  98. thread-8:b:50 
  99. thread-9:a:50 
100. thread-9:b:50 
分享到:
评论

相关推荐

    C++多线程原子操作

    `Interlocked.Increment(ref safeInstanceCount)`会原子性地增加`safeInstanceCount`的值,而`Interlocked.Decrement(ref safeInstanceCount)`则是原子性地减少它。这样,即使在多线程环境下,这些操作也不会因为...

    易语言线程安全之原子锁与读写锁

    易语言提供了原子加减、原子比较并交换(CAS)等原子操作,确保了这些操作的线程安全性。 读写锁则是一种更高级的同步机制,它允许多个线程同时读取共享资源,但只允许一个线程进行写入。这种锁的特性提高了多线程...

    多线程程序中的原子操作

    1. **Guaranteed Atomic Operations**:一些基本的内存读写操作是被硬件提供的原子性保证所支持的,如读写单个字节的操作。 2. **Bus Locking**:使用LOCK#信号和LOCK指令前缀来锁定总线,确保某些特定操作(如读-...

    java多线程中的原子操作

    在Java中,`java.util.concurrent.atomic`包提供了多种原子类,如AtomicInteger、AtomicLong等,这些类支持原子性的增加、减小、更新等操作,避免了显式的同步锁的使用,提高了并发性能。例如,AtomicInteger的...

    Java多线程中提到的原子性和可见性、有序性1

    Java多线程编程中,原子性、可见性和有序性是三个关键的概念,它们确保了多线程环境下的正确性。 1. 原子性(Atomicity) 原子性指的是一个操作不可被中断,要么全部执行,要么完全不执行。在Java中,非原生类型的...

    多线程:可见性、有序性、原子性.xmind

    多线程:可见性、有序性、原子性.xmind

    java多线程安全性基础介绍.pptx

    原子性 竞态条件 i++ 读i ++ 值写回i 可见性 JMM 由于cpu和内存加载速度的差距,在两者之间增加了多级缓存导致,内存并不能直接对cpu可见。 各线程之间变量不可见,线程通信通过共享主内存实现。 ...

    并发二:原子性、可见性、有序性.pdf

    原子性是指一个操作不会被线程调度机制打断,一旦开始,就一直运行到结束,中间不会有任何线程切换(context switch)。原子性可以保障读取到的某个属性的值是由一个线程写入的。变量不会在同一时刻受到多个线程同时...

    java 并发操作之原子性与可视性1

    在Java并发编程中,原子性和可见性是两个关键的概念,它们直接影响着多线程环境下的程序行为和数据一致性。理解这两个概念对于编写高效且线程安全的代码至关重要。 首先,让我们详细探讨一下原子性。原子性指的是一...

    Java多线程:AtomicIntegerArray 原子更新数组类.docx

    Java中的`AtomicIntegerArray`是`java.util.concurrent.atomic`包中的一个类,它提供了一种在多线程环境下原子性地更新整型数组元素的方法。这个类和其他两个类似类——`AtomicLongArray`(用于原子更新长整型数组)...

    Java多线程编程的线程安全性.docx

    线程安全性的核心问题主要包括原子性、可见性和有序性。 **一、线程安全性** 线程安全的定义是:当多个线程同时访问某个类时,无论运行环境如何调度线程执行,也不需要额外的同步或协调,这个类都能保持正确的行为...

    10 有福同享,有难同当—原子性.pdf

    本章将通过“有福同享,有难同当—原子性”这一主题,深入探讨并发编程中的核心概念——原子性,以及与之相关的线程安全和并发编程的三大特性。 并发编程的三大特性包括原子性、可见性和有序性。这些特性是理解和...

    java并发理论基础、可见性、原子性、有序性详解

    然而,并发编程也带来了一系列挑战,如线程安全、可见性、原子性和有序性问题。 **并发理论基础**: 并发编程的核心在于多线程,允许多个执行单元在同一时间执行任务,以充分利用系统资源。在Java中,通过创建...

    java线程安全性精讲.docx

    Java提供了多种机制来确保线程安全,主要包括原子性、可见性和有序性。 **原子性**是线程安全的基础,保证了操作不会被其他线程打断。Java提供了一些原子类,如`AtomicInteger`、`AtomicLong`等,它们使用了无锁...

    Java内存模型--原子性;有序性;可见性1

    总结来说,Java内存模型通过原子性、有序性和可见性保证了多线程环境下的数据一致性。理解并熟练运用这些概念是编写高效、线程安全的Java代码的基础。在实际开发中,应根据需求选择合适的方式来确保这三个特性,以...

    14、深入理解并发可见性、有序性、原子性与JMM内存模型(1).pdf

    在这个示例中,`counter++`操作虽然简单,但在多线程环境下并非原子性的。这是因为该操作实际上包括读取、计算和写回三个步骤,这三步操作可能会被其他线程的操作打断,导致最终的结果小于预期的100000。 #### 2. ...

    用原子自旋读写锁代替互斥锁提高多线程访问公共资源效率

    首先,原子自旋锁的核心在于原子操作,如CAS(Compare and Swap)指令,这是一个无锁编程中的基础操作,可以确保在多线程环境下对共享变量的修改是原子性的,不会被其他线程中断。 当线程试图获取自旋锁时,它会...

    CVI 线程锁、线程安全变量实例

    在LabWindows/CVI中,实现线程安全变量可能需要使用特定的线程库函数,如`cvAtomicInc()` 和 `cvAtomicDec()`,它们提供原子性地增加或减少变量的值。此外,还可以使用`cvMutexVar`结构体来创建自定义的线程安全变量...

    线程安全、volatile关键字、原子性、并发包、死锁、线程池.md

    线程安全、volatile关键字、原子性、并发包、死锁、线程池学习笔记

Global site tag (gtag.js) - Google Analytics