Chinaunix首页 | 论坛 | 博客
  • 博客访问: 610214
  • 博文数量: 72
  • 博客积分: 1177
  • 博客等级: 少尉
  • 技术积分: 856
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-23 23:03
文章分类

全部博文(72)

文章存档

2015年(13)

2014年(5)

2013年(7)

2012年(39)

2011年(8)

分类: Java

2012-08-01 21:32:31

当两个或多个线程需要访问同一共享资源时,需要确保资源在同一时刻只能被同一线程使用,称之为同步。同步的关键是semaphore(信号量),也称之为Monitor(监视器)。一个监视器是作为互斥排他锁mutex使用的一个对象。

点击(此处)折叠或打开

  1. package semaphore;

  2. public class Callme {
  3.      void call(String msg)
  4.      {
  5.          System.out.print("["+msg);
  6.              try {
  7.                 Thread.sleep(1000);
  8.             } catch (InterruptedException e) {
  9.                 // TODO Auto-generated catch block
  10.                 System.out.println("Interrupted");
  11.             }
  12.         System.out.println("]");
  13.      }
  14. }

点击(此处)折叠或打开

  1. package semaphore;

  2. public class Caller implements Runnable{
  3.      String msg;
  4.      Callme target;
  5.      Thread t;
  6.      public Caller(String msg,Callme target)
  7.      {
  8.          this.target=target;
  9.          this.msg=msg;
  10.          t=new Thread(this);
  11.          t.start();
  12.      }
  13.      @Override
  14.      public void run()
  15.      {
  16.          this.target.call(msg);
  17.      }
  18. }

点击(此处)折叠或打开

  1. package semaphore;
  2. class Synch{
  3. public static void main(String args[])
  4. {
  5.      Callme target = new Callme();
  6.      Caller obj1 = new Caller("Hello",target);
  7.      Caller obj2 = new Caller("chen",target);
  8.      Caller obj3 = new Caller("dong",target);
  9.              try {
  10.                 obj1.t.join();
  11.                 obj2.t.join();
  12.                 obj3.t.join();
  13.             } catch (Exception e) {
  14.                 // TODO: handle exception
  15.                 System.out.println("Interrupted");
  16.             }
  17. }
  18. }
运行结果:
[Hello[dong[chen]
]
]


对call()的访问进行序列化,加上synchronized,限制某一时刻只有一个线程访问它。
synchronized void call(String msg);

序列化后的运行结果:
[Hello]
[dong]
[chen]

但是,如果想同步访问没有设计为多线程访问的类的对象,比如说用的是第三方的类,不能修改源码,上述方法就不能解决同步访问的问题了,同步访问方式如下:
synchronized(object)
{
//statements to be synchronized
}
这里object对象是需要同步的对象的引用。下面代码在run()方法中使用了同步块。

public class Caller implements Runnable{
 String msg;
  Callme target;
  Thread t;
  public Caller(String msg,Callme target)
  {
  this.target=target;
  this.msg=msg;
  t=new Thread(this);
  t.start();
  }
  @Override
  public void run()
  {
  synchronized(this.target){
  this.target.call(msg);
  }
  }
}

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