Chinaunix首页 | 论坛 | 博客
  • 博客访问: 749262
  • 博文数量: 130
  • 博客积分: 2951
  • 博客等级: 少校
  • 技术积分: 1875
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-04 18:32
文章分类

全部博文(130)

文章存档

2013年(1)

2012年(129)

分类: Java

2012-03-29 15:57:47

小华是个3岁的孩子,刚刚学会从1数到100,我们分别启动两个线程,在每个线程里都让小华从1数到100,在不对线程进行同步的情况下,刚刚学会数数的小华数乱了。。


点击(此处)折叠或打开

  1. package intro.thread;

  2. class Child{
  3.     public void count(){
  4.         for(int i = 0; i < 100; i++){
  5.             System.out.println(i);
  6.         }
  7.     }
  8. }

  9. class ThreadA extends Thread{
  10.     private Child Child = null;
  11.     public ThreadA(Child Child){
  12.         this.Child = Child;
  13.     }
  14.     
  15.     public void run(){
  16.         Child.count();
  17.     }
  18.     
  19. }


  20. public class ThreadTest {
  21.     public static void main(String [] args){
  22.         Child Child = new Child();
  23.         ThreadA A1 = new ThreadA(Child);
  24.         ThreadA A2 = new ThreadA(Child);
  25.         
  26.         A1.start();
  27.         A2.start();
  28.     }    
  29. }
结果:

点击(此处)折叠或打开

  1. 1 2 3 4 5 6 7 8 9 10
  2. 11 12 13 14 15 16 17 18 19 20
  3. 21 22 23 24 25 26 27 28 29 30
  4. 31 32 33 34 35 36 37 38 39 40
  5. 41 42 43 44 45 46 47 48 49 50
  6. 51 52 53 54 55 56 57 58 59 60
  7. 61 62 63 64 65 66 67 68 69 70
  8. 1 2 3 4 5 6 7 8 9 10
  9. 11 12 13 14 15 16 17 18 19 20
  10. 21 22 23 24 25 26 27 28 29 30
  11. 31 32 33 34 35 36 37 38 39 40
  12. 41 42 43 44 45 46 47 48 49 50
  13. 51 52 53 54 55 56 57 58 59 60
  14. 71 72 73 74 75 76 77 78 79 80
  15. 81 82 83 84 85 86 87 88 89 90
  16. 61 62 63 64 65 66 67 68 69 70
  17. 71 72 73 74 75 76 77 78 79 80
  18. 81 82 83 84 85 86 87 88 89 90
  19. 91 92 93 94 95 96 97 98 99 100
  20. 91 92 93 94 95 96 97 98 99 100
那么如何让宝宝能顺利的数完2遍呢?只好让他先数完第一遍,再数第二遍了

把Child类的Count方法改为:

点击(此处)折叠或打开

  1. public synchronized void count(){
  2.         StringBuffer sb = new StringBuffer();
  3.         for(int i = 1; i <= 100; i++){
  4.             //System.out.println(i);            
  5.             sb.append(i);
  6.             sb.append(" ");
  7.             if(i % 10 == 0){
  8.                 System.out.println(sb.toString());
  9.                 sb.delete(0, sb.toString().length());
  10.             }
  11.         }
  12.     }
这样synchronized锁定的是调用count这个同步方法的对象,所以在A1线程中,宝宝开始从1开始数,
这时候A2线程中,宝宝也准备开始数,但是这个方法由于已经被synchronized, 所以只能等A1中
宝宝数完后,再继续运行。
注意的是,对于方法进行synchronized, 锁定的是同一个访问这个方法的对象。如果有两个宝宝都从
1数到100,那么将会发生什么呢?

点击(此处)折叠或打开

  1. package intro.thread;

  2. class Child{
  3.     public synchronized void count(){
  4.         StringBuffer sb = new StringBuffer();
  5.         for(int i = 1; i <= 100; i++){
  6.             //System.out.println(i);            
  7.             sb.append(i);
  8.             sb.append(" ");
  9.             if(i % 10 == 0){
  10.                 System.out.println(sb.toString());
  11.                 sb.delete(0, sb.toString().length());
  12.             }
  13.         }
  14.     }
  15. }

  16. class ThreadA extends Thread{
  17.     private Child Child = null;
  18.     public ThreadA(Child Child){
  19.         this.Child = Child;
  20.     }
  21.     
  22.     public void run(){
  23.         Child.count();
  24.     }
  25.     
  26. }


  27. public class ThreadTest {
  28.     public static void main(String [] args){
  29.         Child Child1 = new Child();
  30.         Child Child2 = new Child();
  31.         ThreadA A1 = new ThreadA(Child1);
  32.         ThreadA A2 = new ThreadA(Child2);
  33.         
  34.         A1.start();
  35.         A2.start();
  36.     }    
  37. }
结果:

点击(此处)折叠或打开

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

那么对于两个不同的宝宝,也想对线程进行同步,让其中一个宝宝数完后,下一个宝宝再继续数,该如何呢?
那么需要对Child类做如下修改:

点击(此处)折叠或打开

  1. class Child {

  2.     static Object obj = new Object();

  3.     public void count() {
  4.         synchronized (obj) { //必须是对静态对象加锁
  5.             StringBuffer sb = new StringBuffer();
  6.             for (int i = 1; i <= 100; i++) {
  7.                 // System.out.println(i);
  8.                 sb.append(i);
  9.                 sb.append(" ");
  10.                 if (i % 10 == 0) {
  11.                     System.out.println(sb.toString());
  12.                     sb.delete(0, sb.toString().length());
  13.                 }
  14.             }
  15.         }
  16.     }
  17. }



























阅读(1155) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~