当两个或多个线程需要访问同一共享资源时,需要确保资源在同一时刻只能被同一线程使用,称之为同步。同步的关键是semaphore(信号量),也称之为Monitor(监视器)。一个监视器是作为互斥排他锁mutex使用的一个对象。
- package semaphore;
- public class Callme {
- void call(String msg)
- {
- System.out.print("["+msg);
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- System.out.println("Interrupted");
- }
- System.out.println("]");
- }
- }
- package semaphore;
- 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()
- {
- this.target.call(msg);
- }
- }
- package semaphore;
- class Synch{
- public static void main(String args[])
- {
- Callme target = new Callme();
- Caller obj1 = new Caller("Hello",target);
- Caller obj2 = new Caller("chen",target);
- Caller obj3 = new Caller("dong",target);
- try {
- obj1.t.join();
- obj2.t.join();
- obj3.t.join();
- } catch (Exception e) {
- // TODO: handle exception
- System.out.println("Interrupted");
- }
- }
- }
运行结果:
对call()的访问进行序列化,加上synchronized,限制某一时刻只有一个线程访问它。
synchronized void call(String msg);
序列化后的运行结果:
但是,如果想同步访问没有设计为多线程访问的类的对象,比如说用的是第三方的类,不能修改源码,上述方法就不能解决同步访问的问题了,同步访问方式如下:
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);
}
}
}
阅读(1498) | 评论(0) | 转发(1) |