Chinaunix首页 | 论坛 | 博客
  • 博客访问: 44000
  • 博文数量: 10
  • 博客积分: 253
  • 博客等级: 二等列兵
  • 技术积分: 131
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-09 08:08
文章分类
文章存档

2012年(10)

我的朋友

分类:

2012-04-13 19:10:52

今天偶然翻开上学期的操作系统笔记,看到线程同步那块,记着当时首先讲的是锁,之后讲了semaphore。
 
-先复习下基本概念
   一个二元信号量和一个锁有相同的功能
   一个初始成0的信号量,就可用来阻塞一个线程
   信号量和锁不同的地方在于,对于锁来说,进行lock和unlock的线程是同一个,而对于信号量来讲,P和V操作并不一定是同一个线程执行的。
 
-为了复习,就实现了一个很简单的Semaphore类,用到了锁。有什么不正确的地方,还请大家指正。

点击(此处)折叠或打开

  1. package semaphore;

  2. public class Semaphore {

  3.     private int count;
  4.     private Object mutex;//这个锁是必须要用的,因为这里有个count变量会被很多线程共享使用

  5.     
  6.     //这两个string是做测试用的

  7.     private final String message_1 = " I get a place !!";
  8.     private final String message_2 = " I 've leaved !!";

  9.     public Semaphore(int n) {

  10.         this.count = n;
  11.         this.mutex = new Object();

  12.     }

  13.     public void P_operation(String name) throws InterruptedException {

  14.         synchronized (mutex) {

  15.             while (count == 0) {
  16.                 System.out.println(name + " is waiting");
  17.                 mutex.wait();
  18.             }

  19.             count--;
  20.             System.out.println(name+message_1);

  21.         }

  22.     }

  23.     public void V_operation(String name) {

  24.         synchronized (mutex) {
  25.             count++;
  26.             System.out.println(name+message_2);
  27.             mutex.notify();
  28.         }

  29.     }

  30. }
-下面假设如下场景,用刚刚实现的semaphre来模拟一下
一个停车场,有3个车位,现在有10个顾客要来停车。当还有空位时,顾客可以进入,否则就一直等到有空位为止。假设每个顾客要停车的时间是随机的。
 
先定义Park线程类
 

点击(此处)折叠或打开

  1. package semaphore;

  2. public class Park extends Thread {

  3.     private Semaphore sph;
  4.     private String name;

  5.     public Park(Semaphore s, String name) {

  6.         super(name);
  7.         this.name = name;
  8.         this.sph = s;

  9.     }

  10.     public void parking() {

  11.         try {
  12.             Thread.sleep((long) (Math.random() * 1000));
  13.         } catch (InterruptedException e) {
  14.             e.printStackTrace();
  15.         }

  16.     }

  17.     public void run() {
  18.         //先尝试获得一个空位
  19.         try {
  20.             sph.P_operation(name);
  21.         } catch (InterruptedException e1) {
  22.             e1.printStackTrace();
  23.         }
  24.         //得到停车位,停车ing....
  25.         parking();
  26.         //要离开了,把车位还回
  27.         sph.V_operation(name);
  28.     }

  29. }

 

-main


 

点击(此处)折叠或打开

  1. package semaphore;

  2. public class Main {
  3.     public static void main(String[] args) {
  4.         
  5.         Semaphore sph = new Semaphore(3);
  6.         
  7.         Thread []park = new Thread[10];
  8.         
  9.         for(int i = 0;i<10;i++){        
  10.             park[i] = new Park(sph,"client-"+i);
  11.             park[i].start();
  12.         }
  13.         
  14.     }
  15. }

打印结果如下


 

点击(此处)折叠或打开

  1. client-0 I get a place !!
  2. client-4 I get a place !!
  3. client-1 I get a place !!
  4. client-2 is waiting
  5. client-3 is waiting
  6. client-6 is waiting
  7. client-8 is waiting
  8. client-5 is waiting
  9. client-7 is waiting
  10. client-9 is waiting
  11. client-4 I 've leaved !!
  12. client-2 I get a place !!
  13. client-0 I 've leaved !!
  14. client-3 I get a place !!
  15. client-3 I 've leaved !!
  16. client-6 I get a place !!
  17. client-2 I 've leaved !!
  18. client-8 I get a place !!
  19. client-1 I 've leaved !!
  20. client-5 I get a place !!
  21. client-5 I 've leaved !!
  22. client-7 I get a place !!
  23. client-8 I 've leaved !!
  24. client-9 I get a place !!
  25. client-6 I 've leaved !!
  26. client-9 I 've leaved !!
  27. client-7 I 've leaved !!



顺便想说的是,jdk引入条件变量后,在程序中就可以更精确的控制同步。

比如上面的例子改一下,顾客中存在优先级别,比如有vip和普通顾客,那么,要就vip优先得到车位。即对于普通顾客来说,得到车位的条件是 -有车位&vip已经得到车位-。

此时,我们需要有两个等待队列,这里不算object的锁队列

对于一个普通顾客来说,可能他首先被加入到等待空闲车位的队列,当某时刻被唤醒后,可能又进入了等待vip的队列

类似这种有优先级的问题,如果只使用信号量来实现,会很麻烦,有了条件变量,就方便多了,可以自定义需要的等待队列。

---------------------------------------------------

周一就开学了,这一周假期好快啊


 



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