2 kefeiol kefeiol 于 2016.04.03 12:28 提问

java 并发处理耗时操作的问题

刚刚写了个测试程序 原本想使用多线程并发处理 来节省时间,结果反而更耗时。请各位指点一下。
主方法:
public class MainAction {
public static void main(String[] args) {
/*new Action1().run();
new Action2().run();
new Action3().run();*/

    new Thread(new Action1()).start();
    new Thread(new Action2()).start();
    new Thread(new Action3()).start();
}

}
Action1 /2/3(方法一样,只是文件大小不同):
public class Action1 implements Runnable{

public void run() {
    System.out.println("start 1..........");
    long start1 = System.currentTimeMillis();
    writeToTxt("123");
    Context.flg1 = 1;
    long end1 = System.currentTimeMillis();
    float second1 = (end1 - start1) / 1000F;
    System.out.println("end 1 cost " + second1 + " s");
}
public void writeToTxt(String text){
    File file = new File("D:/1.txt");
    FileWriter fw = null;
    BufferedWriter writer = null;
    try {
        fw = new FileWriter(file);
        writer = new BufferedWriter(fw);
        for (int i=0;i<200*1000*10;i++) {
             writer.write(text);
             writer.newLine();//换行
        }
        writer.flush();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }catch (IOException e) {
        e.printStackTrace();
    }finally{
        try {
            writer.close();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

}

运行结果:
start 1..........
start 2..........
start 3..........
end 2 cost 89.906 s
end 3 cost 115.905 s
end 1 cost 163.817 s

如果使用上面注掉的串行 运行:
start 1..........
end 1 cost 13.681 s
start 2..........
end 2 cost 18.752 s
start 3..........
end 3 cost 20.051 s

求解,是不是程序并没有真正的多线程去执行。
另外,如果Action1/2/3 是3个远程调用,能否达到节省时间的效果?

1个回答

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.04.03 13:01
已采纳

首先,你的代码没有问题,肯定是启动了3个线程来执行任务的。
其次,分析下直接用main线程顺序执行三个操作,为什么比同时启动三个线程执行速度快呢?我认为这又可能跟操作系统处理IO的方式有关系,多线程并发处理IO时,操作系统底层响应IO的速度会影响线程的操作的。单线程环境下,顺序执行IO,操作系统可能不涉及到对IO请求的调用问题,但是多个线程同时发出IO请求命令时,操作系统底层的调度也有影响。
你可以修正下你的测试内容,把Action中的Runnable的任务换成其他长时间计算任务,例如休眠操作,或者大数据计算操作,那么多线程的优势就体现出来了。
修正测试内容:

    public void writeToTxt(String text) {
        int j=0;
        for(int i =0;i<1000000;i++){
         j=i    ;
        }
        System.out.println(Thread.currentThread().getName()+j);
    }

最后,多线程提高效率体现在对整个功能完成时间上,是并行,而不会是纠结于单个任务完成过程中的处理时间;从理论上说,一个Runnable中执行完成的时间应该是差不多的,多线程的优势就是N个任务并行时,需要的总时间近似于完成一个任务的时间;而单线程时间则是N倍的单个任务的时间。而且多线程要考虑到线程池创建和调度的时间损耗,还是需要权衡的。像这种类似任务可以用java的线程池,可以免去线程创建和销毁的损耗。

kefeiol
kefeiol 好的,谢谢你 。下周去公司试一下。
一年多之前 回复
wojiushiwo945you
wojiushiwo945you 回复kefeiol: 是这样的。
一年多之前 回复
kefeiol
kefeiol 你的回答很清晰,其实我这边真实的业务场景就是java读写大文件,不过是分布在不同机器上。所以我的第二个问题,如果这些读写改成接口,多线程远程去调用,那么应该是比串行调用会省时的,对吧
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!