ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 线程模式

线程模式

原创 Linux操作系统 作者:spritesong 时间:2009-03-30 23:45:42 0 删除 编辑
Single Threaded Execution Pattern在什么情况下使用
1.多线程访问同共享资源时时,单线程不需要使用synchronized
2.共享资源状态可能发生变化时

可能产生死锁的情况:
1.可能存在多个共享资源时
2.线程锁定一个共享资源时,还没解锁就去锁定另外一个共享资源.
3.获取共享资源 参与者的顺序不固定.

例如:(一个叉子,一个刀两个共享资源 两个线程各自拥有一个资源的锁,两者都在等待对方解锁 )
解决方法:
  1.同时获取两个共享资源的锁
 
或者(一个输入队列,一个输出队列个共享资源 两个线程各都没有拥有一个资源的锁,而两者都处于释放锁 )
解决方法:
  开始时使获取输入队列的锁,


Immutable Thread Pattern
当shared resources的成员变量使类实例时,这个实例的类如果是Immutable类,那么这个shared resource就是线程安全的
比如String,如果不是,就算由final修饰也是不一定的;比如一个Point类,除非满足以下的条件
1.将Point类的x字段和y字段都设成为public final
2.我们要建立一个拥有与所给的实例相同属性的新实例,将此新实例指定到字段中.例如:
public class Line{
  private final Point startPoint;
  private final Point endPoint;
  public Line(int startx,int starty,int endx,int endy)
    this.startPoint = new Point(startx,starty);
    this.endPoint = new Point(endx,endy);
   
}

public Line(Point startPoint,Point endPoint){
    this.startPoint = new Point(startPoint.x,startPoint.y);
    this.endPoint = new Point(endPoint.x,endPoint.y);
}


Guarded Suspension Pattern:满足条件才执行,否则就一直等待
最普通的阻塞形式
while ("警戒条件"的逻辑否定){
    使用wait等待;
}
进行目的操作;

等待端的范例:
while (!ready){
  wait();
}
dosth();
唤醒端的范例:
ready = true;
notifyAll();

忙碌的等待:busy wait:线程不使用wait等待,而是使用yield(尽可能把优先级交给其他的线程)
等待端的范例:
while(!ready){
  Thread.yield();
}

唤醒端的范例:
ready = true;
注意:yield不会接触锁定,所以程序不能写在synchronized,而ready必须声明称volatile

唤醒后,即执行了notify或者nofifyall后,一定要再次检查警戒条件,因此必须用while



balk thread pattern:当共享资源拥有的状态满足条件时,才执行,否则就什么也不做(返回)
只进行一次初始化的类
public class Something{
  private boolean initialized = false;
 
  public synchronized void init(){
      if (initialized) {
        return;
    }
    doinit();
    initialized =true;
  }
 
  private void doInit(){}
}

Producer-Consumer Pattern
中间者的存在隐含的意义
线程的合作要想"放在中间的东西"
线程的互斥要想"应该保护的东西"

interrupt方法和interrupted方法
interrupt:将线程切换到中断状态的方法.
interrupted:检查并清除中断状态的方法.

Read-Write Lock Pattern
一般来说,进行共享互斥会使程序性能变差,但将写入的共享互斥与读取的共享互斥分开来思考,就可以提升程序的性能.

前置处理(获取锁定)
try{
  实际操作
}
finally{
  后续处理(解除锁定)
}

synchronized(锁定用的实例){
  实际的操作
}这两种写法都会执行:
获取锁定
   |
实际的操作
   | 
解除锁定

数组间的拷贝一般可以用:arrayCopy

利用同时读取不会冲突的特性提高程序的性能
1.适合读取操作繁重时,单纯使用Single Thread Exception Pattern时,连read操作,一次也只有一条线程可以执行.
2.适合读取比写入更加频繁时


Thread-Per-Message Pattern:
client参与者会调用host参与者的request方法送出请求.实际处理请求的时helper的handle方法.但是如果client参与者调用
request的方法,而在request方法里面又调用handle方法,在实际的操作结束之前不会退出handle方法,这样会使request的响应性降低.
因此,我们在host里面启动一个新的线程来处理这个请求.由这个新的请求来调研handle方法.
例如一般的形式为:
public class className{
  public void Service{
    System.out.println("service");
    //start thread   
    new thread(){
      public void run(){
        doService
      }
    }.start();//inner class
  }
 
  //这个doService 可以按照实际的情况变化:加synchronized变为 single thread execution模式;加if判断变为balk thread patterh
  private static synchronized void doServide(){
    doStrh;
    try{
      Thread.sleep(100);
    }
    catch(InterruptedException e)
  }
 
}


Worker Thread Pattern
invocation和execution的分离:与普通的调用方法操作,启动方法和执行方法是连续执行的,即启动和执行是密不可分的
但是worker thread pattern和thread-per-message patter ,我们刻意将方法的启动和执行分开

Request参与者是个真正要执行的对象,里面封装了执行的一些必须数据,在ClinetThread被创造,通过channel传递到workerthread,在其里面被真正执行

注册Listener的意义:对组件设置当事件发生时,Event-dispatching thread所要调用的方法所在的实例
 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/293106/viewspace-582258/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 保存客户信息
请登录后发表评论 登录
全部评论

注册时间:2009-03-28

  • 博文量
    62
  • 访问量
    24836