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所要调用的方法所在的实例
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/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/293106/viewspace-582258/