线程笔记之并发同步
在应用编程中,我们会遇到下面这样的调用模型。。。
当一个业务方法(begin)中顺序调用多个子业务方法(opertion1-N),且有些子业务方法比较耗时,那么自然而然完成这次调用所需要的时间就比较长了。对于这样的问题,通常情况下会从两个方面对其进行重构和调优:
单个方法调优,即针对operation1-N中比较耗时的方法进行重构已达到期望的效果
业务重组和方法重构,即对整个大的业务方法进行重组,找出合乎当前需求(功能和性能)的实现方式
1比较好理解,最常见的就是sql语句,IO和string buffer方面的调优;2则需要看具体的应用场景了。由于本文主要是侧重线程的并发与同步,所以我将例举一个比较特殊的场景(webservices 远程调用)。如下:
对照上述序列图,若每一个operation方法都将进行一次远程webservice调用,那么一次调用的代价就要包含网络通信方面的开销。如果网络延时很高,多次远程调用的代价就相当大了。那么该如果结合上面的第2点进行重构和调优呢?
减少网络调用次数。 例如 operation1->API1,operation2->API2, 那么是否可以提供一个包含API1和API2的新API12供其调用呢?这样一次调用就可以达到目的。
多线程调用。如,让operation1与operation2并发,这样调用所需要的时间则为max(cost(operation1), cost(operation2))。这样做会大大提高系统的复杂性,谨慎而为之。
接下来进入主题,谈谈并发的具体实现方式。
基本测试类ConcurrentSimpleTest
Java代码
public class ConcurrentSimpleTest {
public void method1() {
System.out.println("before exec method1");
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("method1 has been interrupted.");
e.printStackTrace();
}
System.out.println("after exec method1");
}
public void method2() {
System.out.println("before exec method2");
try {
Thread.sleep(800);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("method2 has been interrupted.");
e.printStackTrace();
}
System.out.println("after exec method2");
}
}
方式1:使用线程的join方法
Java代码
public static void main(String[] args) throws InterruptedException {
final ConcurrentSimpleTest cst = new ConcurrentSimpleTest();
long s1 = System.currentTimeMillis();
cst.method1();
cst.method2();
long s2 = System.currentTimeMillis();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
cst.method1();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
cst.method2();
}
});
t1.start();
t2.start();
t1.join(); //t2.join(500); 实际400ms后,方法就返回了
t2.join(); //t1.join(x); if x< max((800 - 400), (800-500)), 那该方易做图在t2执行完前返回
//线程1/2都已返回,需要验证结果
long s3 = System.currentTimeMillis();
System.out.println("time cost for normal execution:" + (s2-s1));
System.out.println("time cost for concurrent execution:" + (s3-s2));
}
方式2:使用信号量对象
自定义信号量
Java代码
public class SimpleMonitor {
public volatile int single = 0;
public void require(int single) {
this.single = single;
}
public synchronized void release(int single) {
this.single -= single;
this.notify();
}
}
Java代码
public static void main(String[] args) throws InterruptedException {
final ConcurrentSimpleTest cst = new Concur
补充:软件开发 , Java ,