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个回答

首先,你的代码没有问题,肯定是启动了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 好的,谢谢你 。下周去公司试一下。
3 年多之前 回复
wojiushiwo945you
毕小宝 回复kefeiol: 是这样的。
3 年多之前 回复
kefeiol
kefeiol 你的回答很清晰,其实我这边真实的业务场景就是java读写大文件,不过是分布在不同机器上。所以我的第二个问题,如果这些读写改成接口,多线程远程去调用,那么应该是比串行调用会省时的,对吧
3 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
java 并发处理耗时操作的问题
刚刚写了个测试程序 原本想使用多线程并发处理 来节省时间,结果反而更耗时。请各位指点一下。n主方法:npublic class MainAction n public static void main(String[] args) n /*new Action1().run();n new Action2().run();n new Action3().run();*/n n new Thread(new Action1()).start();n new Thread(new Action2()).start();n new Thread(new Action3()).start();n nnAction1 /2/3(方法一样,只是文件大小不同):npublic class Action1 implements Runnablenn public void run() n System.out.println("start 1..........");n long start1 = System.currentTimeMillis();n writeToTxt("123");n Context.flg1 = 1;n long end1 = System.currentTimeMillis();n float second1 = (end1 - start1) / 1000F;n System.out.println("end 1 cost " + second1 + " s");n n public void writeToTxt(String text)n File file = new File("D:/1.txt");n FileWriter fw = null;n BufferedWriter writer = null;n try n fw = new FileWriter(file);n writer = new BufferedWriter(fw);n for (int i=0;i<200*1000*10;i++) n writer.write(text);n writer.newLine();//换行n n writer.flush();n catch (FileNotFoundException e) n e.printStackTrace();n catch (IOException e) n e.printStackTrace();n finallyn try n writer.close();n fw.close();n catch (IOException e) n e.printStackTrace();n n n n nn运行结果:nstart 1..........nstart 2..........nstart 3..........nend 2 cost 89.906 snend 3 cost 115.905 snend 1 cost 163.817 snnn如果使用上面注掉的串行 运行:nstart 1..........nend 1 cost 13.681 snstart 2..........nend 2 cost 18.752 snstart 3..........nend 3 cost 20.051 snn求解,是不是程序并没有真正的多线程去执行。n另外,如果Action1/2/3 是3个远程调用,能否达到节省时间的效果?n
操作耗时问题!急!
我想记录一下一个操作的所耗时间。rn比如说读取SQL数据库所用时间,应该怎样操作?
java 多线程 传参 并发处理
众所周知,只要涉及多线程或者分布式,肯定是要处理传参和处理并发的问题。 1.传参 多线程的传参,和java里普通类的传参很类似,一般是两种方式,构造方法和set方法 1.1构造方法 public class Test02 { public static void main(String[] args) { R r = new R("mike"); Thread t = n
Java开发手册精选-并发处理
一 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。 说明: 使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统开销,解决资源不足的问题。 二 线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors返回的线程池对象的弊端如下: FixedThread...
java 多线程 并发处理
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。(进程是资源分配的最小单位)  线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)   线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。   多进程是指操作系统能同时运行多个任务(程序)。   多线...
Swift-处理耗时操作
在下载文件处理时会好耗时操作,使用线程可以有效处理耗时操作 //添加任务队列 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in //处理耗时操作 //操作完成后调用主线程刷新界面
winform处理耗时操作
程序是扫描局域网里的主机:rn[code=csharp]rn public delegate void OnUiControl();rn private void button1_Click(object sender, EventArgs e)rn rn Thread thScan = new Thread(new ThreadStart(DoControl)); rn thScan.IsBackground = true;rn thScan.Start();rn rn private void DoControl()rn rn OnUiControl uicontrol = this.ScanTarget;rn if (this.InvokeRequired)rn rn this.Invoke(uicontrol);rn rn rn rn private void ScanTarget()rn rn string strIPAddress = "172.30.81."; //ip段rn int nStrat = Int32.Parse("2"); //开始扫描地址rn int nEnd = Int32.Parse("50"); //终止扫描地址rn //开始扫描(耗时操作)rn for (int i = nStrat; i <= nEnd; i++)rn rn string strScanIPAdd = strIPAddress + i.ToString();rn IPAddress myScanIP = IPAddress.Parse(strScanIPAdd); //转换成IP地址 rn tryrn rn //当执行下面这个操作时候比较耗时rn IPHostEntry myScanHost = Dns.Resolve(strScanIPAdd); rn string strHostName = myScanHost.HostName;rn richTextBox1.AppendText(strHostName + "\r");rn Application.DoEvents();rn rn rn catch (Exception error)rn rn MessageBox.Show(error.Message);rn rn rn rnrn[/code]rn上面是原程序,为什么使用了多线程后界面还会卡死呢?求解
不同内存区域的耗时操作
空的for循环不耗性能,基本不耗时 #pragma mark - 耗时操作- (void)longOperation { // 性能测试: double start = CACurrentMediaTime(); for (int i = 0; i < 1000000; i++) { //循环内没有任操作 } // 获取时间差值 NSL
回调 处理耗时操作
/** * 获取绑定的手机号 * @param context * @param callback */ public static void getBindPhone(Context context, final PhoneCallback callback) { //这里是耗时操作 //返回结果 回调 String mPhone = “”; callbac
IntentService中的耗时操作
由于Service和Broadcast都是运行在主线程中,所以在这两个里面我们无法做一些长时间的耗时操作,要执行耗时操作可以用异步线程AsyncTask或者IntentServie。IntentServie的好处是调用玩后会自己关闭service。
Handler耗时操作
一个简单的handler下载做耗时操作的demo
多线程:耗时操作
// // ViewController.m // 01-耗时操作 // // Created by gzxzmac on 16/1/28. // Copyright © 2016年 gzxzmac. All rights reserved. //#import "ViewController.h"@interface ViewController ()@end@implementation
map操作耗时对比
数据显示了10,000,000次迭代以毫秒计的运行时间:   .Hashtable 与 ConcurrentHashMap在可伸缩性方面的比较 线程数 ConcurrentHashMap Hashtable 1 1.00 1.03 2 2.59 32.40 4 5.58 78.23 8 13.21 163.48...
EAS 查看耗时的操作
打开客户端1.ctrl+shift+alt+]  打开录制窗口2.点击录制按钮 3.点击某个操作。如打开序时簿4.操作完成之后,点击暂停按钮,或者停止按钮5.点击查看按钮6.查看耗时操作...
Android耗时操作Demo
Android耗时操作的Handler机制处理:子线程模拟耗时操作(文件下载),并进度条显示下载进度;以及弹出Dialog提示用户正在下载。
耗时操作与UI改变
当在做一个很耗时的操作时,同时改变了UI(添加子视图或者 展示loading小菊花),UI会不起作用 这个时候需要把耗时的操作放到子线程中,异步进行
java接口回掉—异步处理耗时操作
       在Java程序或者是Android程序中,如果需要更新UI必须在主线程中进行,比如你要在网络中获取一个值,然后更新UI。网络获取值属于耗时操作,在主线程中操作的话,会导致线程阻塞,进而导致程序奔溃,所以必须异步进行,问题来了,如果异步进行,如何得知你是否获得了这个值,来通知你更新UI呐,我们可以用接口回掉的方法了,处理这一问题。直接上代码吧定义接口:package Demo1; i...
ios耗时操作
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 耗时的操作 dispatch_async(dispatch_get_main_queue(), ^{ // 更新界面 }); });
处理UI耗时操作
我需要把一个Canvas转成图片,方法如下:rn[code=csharp] MemoryStream myImgMs = null;rn DrawingVisual myDrawingVisual = new DrawingVisual();rn using (DrawingContext context = myDrawingVisual.RenderOpen())rn rn VisualBrush brush = new VisualBrush(pCanvasScrObj) Stretch = Stretch.None ;rn Rect rect = new Rect(new System.Windows.Point(0, 0), new System.Windows.Point(width, height));rn context.DrawRectangle(System.Windows.Media.Brushes.Black, null, rect);rn context.DrawRectangle(brush, new System.Windows.Media.Pen(), rect);rn context.Close();rn rn RenderTargetBitmap bitmap = new RenderTargetBitmap((int)Math.Ceiling(width),rn (int)Math.Ceiling(height), 96, 96, PixelFormats.Pbgra32);rn bitmap.Render(myDrawingVisual);rn PngBitmapEncoder encode = new PngBitmapEncoder();rn encode.Frames.Add(BitmapFrame.Create(bitmap));rn myImgMs = new MemoryStream();rn encode.Save(myImgMs);[/code]rncanvas 可能有2000*3000大小,包含了较多的图片,处理过程比较耗时,运行一次可能需要1-2s时间,并且阻塞UI线程,如果把这个方法放到后台线程的话,还是需要Dispatcher委托给UI线程来完成,会阻塞主线程。各位,不知道有没有方法可以避免阻塞UI线程?写一个WCF服务端,把canvas中数据传给服务端来处理可行么?
IOS--分析耗时操作
IOS–分析耗时操作最近在工作中发现有写页面的tableView存在滑动卡顿的现象,虽然该页面的布局确实很复杂,但是卡顿的程度有的过分,学习到了instrument 另一个小玩意可以来分析我到底是哪里出了问题,在分析之前,tableview 的卡顿原因一般如下: tableview 每行的行高 根据请求的数据 存储下来 不动态计算 异步绘制界面 少用或者不用透明视图 ,省去重新绘制视图的步骤 简单的
java安全并发处理的“套路"
1 synchronized Collections.SynchonrizedMap wait notify voliatile final 2 threadlocal 3 多实例 4 immutable class 5 java.concurrent.util: ReentrantLock ReentrantReadWriteLock CopyOnWriteArrayList Blo...
java多任务并发处理--Callable<?>
在我的工作中,使用多线程的目的只要在于:1、效率大大提升,2、内存能够有效控制,3、代码层次感分明      目前来说,我主要熟知的为以下两种: 一、实现callable的线程,使用ExecutorService executor = Executors.newFixedThreadPool(5);线程池进行并发执行, 具体demo如下: package com.ziglar.c
JAVA中并发处理
多线程问题其实主要可以分为2类问题 1) 数据竞争问题:sync/lock 2) 数据有效性问题:对于volatile修饰的变量,jvm虚拟机可以保证从主内存加载到线程工作内存的值是最新的
java并发处理干货视频
java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频java并发处理干货视频
关于JAVA中高并发处理
JAVA中怎么处理高并发的情况,这里不考虑硬件方面,从代码方面考虑,有知道的吗?求教
并发处理
表A中有一个字段Ord,值是唯一的。当插入新纪录时,Ord取当前表中最大Ord。现假如有两个用户同时操作同一个录入页面,当前表中最大Ord为9,则两个人可能都取10,如何处理这种情况啊?不要取消另一个的操作,而是自动更改它的Ord为11
java链表遍历耗时问题
import java.util.*;rnclass Student rn String name;rn int number;rn Student(String name,int number) rn this.name=name;rn this.number=number; rn rn rn rnpublic class TestIteratorrnrn public static void main(String[] args)rn List list=new LinkedList();rn for(int k=1;k<=22222;k++)rn list.add(new Student("i am"+k,k));rn rn Iterator iter=list.iterator();rn long time1=System.currentTimeMillis();rn System.out.println(time1);rn while(iter.hasNext())rn Student te=(Student)iter.next();rn rn rn long time2=System.currentTimeMillis();rn System.out.println(time2);rn System.out.println("遍历链表用时:"+(time2-time1)+"毫秒");rn time1=System.currentTimeMillis();rn for(int i=0;i
js java输出耗时(时分秒) 统计耗时
//js输出耗时(时分秒) function ms2Hms(ms) { // 毫秒 秒 分 时 var hour = parseInt(ms / 1000 / 60 / 60); // 毫秒 秒 分 var min = parseInt(ms / 1000 / 60 % 60); // 毫秒 秒 var sec = parseInt(ms / 1000 % 60); ...
关于主线程中耗时操作的问题
如下一段代码的截图 为什么要先睡眠3s之后activity_selectcontacts布局才被加载出来呢?加载布局的操作在睡眠的操作前面执行,不是应该先加载布局再睡眠吗? 为什么这样子就能先输出再睡眠呢(如下图)? 二者原理不是一样的吗?都是在主线程中睡眠.为什么结果就不同呢?
主线程阻塞性耗时操作:消息泵问题
[code=C/C++]rnBOOL CMainFrame::PeekAndPump(void)rnrn // message pumprn MSG message; rn while(::PeekMessage(&message,NULL,0,0,PM_REMOVE)) rn rn ::TranslateMessage(&message); rn ::DispatchMessage(&message); rn rn rn // 模拟空闲处理rn //long iCount = 0;rn //while(AfxGetApp()->OnIdle(iCount++));rnrn return TRUE;rnrn[/code]rn主线程里面有个耗时操作( while(1) ... ...),目前不考虑使用多线程取代。我在耗时操作里面掉用了这个消息泵,但是发现一个问题:rn大家注意模拟空闲处理这两句代码rnlong iCount = 0;rnwhile(AfxGetApp()->OnIdle(iCount++));rn如果去掉这两行模拟空闲代码,那么点击按钮之后按钮的状态没有变化(OnUpdateBtn(CCmdUI *pCmdUI)函数)pCmdUI->Enable(!m_bS);并且空闲处理,占去很多时间,比如我100MB文件,本来2s处理,添加空闲模拟后while循环居然需要10几分钟了!rnrn这个是怎么回事?为什么消息泵没有更新按钮状态?这个模拟空闲怎么这么耗费时间?
耗时问题
我有一个主窗口A,弹出子窗口B,B窗口做完了事情后执行window.close(),才可以继续做主窗口A的事情,我在弹出窗口B中执行了耗时操作,有时可能要等二十分钟,如果让用户等二十分钟,再操作其它功能,这太不合理了。rn大家是怎么解决的??
多线程并发处理数据的问题
在现在的项目中遇到的一个问题。 我所做的短信平台,原来只是单线程发送短信的,但是由于公司的应用范围的扩大,短信的发送量成倍的增多,一批插入的短信量达到5W数据,如果按照以前的方式,发送过程十分缓慢。因为我们所用的第三方短信提供商只提供给我们10个并发的限制,所以我们采用10条线程进行读取。一次发10条,等10条发送完成以后再发送另外10条。 以下是程序:   private  void s...
事务并发处理带来的问题
丢失更新 两个人(甲和乙)同时读取一个数据,甲修改完数据并写回数据库。接着乙也修改数据并写回数据库。导致甲的修改被覆盖读脏数据 甲修改了数据,乙读取甲修改后的数据,但由于某种原因甲撤销事务。导致乙读取的数据不正确不可重复读 事务1读取数据后,事务2执行更新操作,使事务1无法再现前一次读取结果。或者说一个事务里读两遍,读出来的值不一致.第二次读到其他事务提交的结果幻读 事务1读的过程之中,另外
sql并发处理的问题.
例如我怎么控制rnbegin tranrnselect @id=id from web_user where username='ll'rnupdate web_t set holdcount=holdcount+100 where userid=@idrncommit tranrnrn怎样能让用户同时触发时不会出现错误.例如两次同时请求,结果只加了100
讨论:数据并发处理的问题!
多用户同时登录一个Web系统,他们将同时看到一条数据记录,而其中一用户删除该记录,希望应用服务器通知其他用户的页面也删除该记录?假如做不到了,至少应该让其他用户知道,该数据记录已经不存在了!rnrn请问各位大侠,是什么方式来实现,比较好?
AJAX中并发处理的问题
在使用DWR开发AJAX的过程中, 出现了这几个问题很麻烦rn 一是点击一个按钮后, 在数据没有返回前又点了下一个按钮, 第二个请求把第一个请求冲掉了 rn 二是点击按钮后, 数据还没返回, 先执行显示数据的代码了,可是没有数据, 所以显示的是空, 或者是上一次请求的数据 rnrn大家在工作中遇到过类似的问题吗, 怎么解决?
关于并发处理数据的问题.
现在有这么一个需求,有六个部门,每个部门要处理一批数据,但是每个部门在处理这批数据的的时间很长。所以想用线程来处理。但是不知道怎么来处理好?望请教?n[b]问题补充:[/b]n我现在就是循环得到某个部门,然后取得当前的部门进行操作,这样的话是同步的,效率很差。
iOS对耗时操作的处理方法
在项目中经常会遇到比较耗时的操作导致界面卡顿,可以尝试使用GCD异步方式处理: dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 处理耗时操作在此次添加//通知主线程刷新 dispatch_async(dispatch_get_main_queue(), ^{ //在主线程刷新UI }); });
验证码 timer timertask handler
Ui代码 xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"
Swing后台耗时操作的处理
  &amp;lt;!--[if !supportLists]--&amp;gt;1.       &amp;lt;!--[endif]--&amp;gt;关于Swing的后台长时操作 在Swing UI当中,如果一个后台操作特别耗时,会导致GUI界面暂时无法响应的情况出现。为了解决这样的问题,引用SwingWorker类来完成后台耗时操作。 其程序框架大致如下: SwingWorker worker = new Sw...
相关热词 c# 去空格去转义符 c#用户登录窗体代码 c# 流 c# linux 可视化 c# mvc 返回图片 c# 像素空间 c# 日期 最后一天 c#字典序排序 c# 截屏取色 c#中的哪些属于托管机制