解决方案 »

  1.   

    笔记本 windows 32bit?
    服务器 windows?linux? 32bit?64bit ?
      

  2.   

    个人觉得可能是jvm的缺省工作模式导致的不同结果。建议楼主指定一下 -server 参数再重新跑跑看。
      

  3.   

    要考虑因素比较多,具体如下:
    1.就像楼上说的工作模式会导致性能的差别;
    2.你服务器和本地的配置差别比较大,就cpu而言一个是双核的,一个是八核的,内存应该也有差别吧。这样的无法验证你认为的“不管多少个线程执行平均时间应该是近似相等的”,应该同一环境下测试;
    3.如果你是在同一环境下测试来验证验证你认为的“不管多少个线程执行平均时间应该是近似相等的”,需要注意当前JVM的CPU、内存、线程等实用情况,比如会不会超过CPU或JVM限制的最大线程数了?是不是内存资源耗尽导致线程分配失败?CPU使用率过高导致无法给新的线程分配时间片?等等;可以实用Jconsole来观察,如下图:4.你说的第2点结论可能是因为JVM工作模式不同导致的;
      

  4.   

    额。怎么一按回车就提交了。关于第4点补充一下:
    4.楼主说的第2点结论可能是因为JVM工作模式不同导致的,也可能是因为你服务器的多核CPU给线程并行执行导致的;对于楼主说的第一点结论,个人认为并不是“修改线程数,得到的时间近似正比翻倍”,也不是“不管多少个线程执行平均时间应该是近似相等的”,而是应该类似抛物线,在某一点CPU资源和JVM线程得到最合理的分配,在这之前线程数和CPU执行时间是成正比;而这之后线程数和CPU执行时间是成反比的,因为过多的线程导致CPU时间片的分配越来越激烈,内存资源可能会被耗尽,线程间频繁的上下文切换也很耗资源;
      

  5.   

    1.修改线程数,得到的时间近似正比翻倍。而按理说排除掉多线程分担掉的cpu消耗,不管多少个线程执行平均时间应该是近似相等的。这是我的程序的BUG还是其他什么的原因?线程之间的互相切换消耗了太多时间.做个实验://.start();改为
     for(i =0;i<LENGTH;i++){
            new Use(true, i).run1();
      }run函数改名做run1修改Length对时间的消耗从此没有影响了。
      

  6.   


    本机为win7 64,服务器为centos6.3 64.
    我不是多么明白工作模式是什么意思,刚刚在本机上跑时我指定了Arguments和jre跑的过程:
    设置线程数为10:
    static avg :377
    non-static avg :281
    设置线程数为20:
    static avg :718
    non-static avg :505
    设置线程数为40:
    static avg :1544
    non-static avg :1275
    有个公式MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads不知道对不对。按照这个公式算出来和我自己测出来的jvm最大线程数是远大于当前程序新开的线程数的。
    因为内存的缘故就完全可以忽略了。
    而CPU时间片~该程序单个执行耗时约50ms。我想约20个线程(不包含其他进程,本机运行时未运行其他任务),应该不存在每个线程还需要轮询吧?(我不知道怎么查询本机的时间片长度)
      

  7.   


    本机为win7 64,服务器为centos6.3 64.
    我不是多么明白工作模式是什么意思,刚刚在本机上跑时我指定了Arguments和jre跑的过程:
    设置线程数为10:
    static avg :377
    non-static avg :281
    设置线程数为20:
    static avg :718
    non-static avg :505
    设置线程数为40:
    static avg :1544
    non-static avg :1275
    有个公式MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads不知道对不对。按照这个公式算出来和我自己测出来的jvm最大线程数是远大于当前程序新开的线程数的。
    因为内存的缘故就完全可以忽略了。
    而CPU时间片~该程序单个执行耗时约50ms。我想约20个线程(不包含其他进程,本机运行时未运行其他任务),应该不存在每个线程还需要轮询吧?(我不知道怎么查询本机的时间片长度)因为不同的工作模式对于线程和函数调用做了不同的优化。你具体可以看上去分别工作在什么模式下面。
      

  8.   

    这个我手动测试了一下:
    新代码:package isStatic;public class UseLittlelong {

    private static int LENGTH = 5;
    private static int[] avg_static = new int[LENGTH];
    private static int[] avg_nonstatic = new int[LENGTH];
    //divided
    private Method m = new Method();

    public static void main(String[] args) {
    UseLittlelong ull = new UseLittlelong();
    //执行时间有点长,可以自由更改,这么写是为了让数据更加平均
    for (int t = 0 ; t < 40 ; t ++) {
    if (t % 8 == 0)
    LENGTH += 5;
    avg_static = new int[LENGTH];
    avg_nonstatic = new int[LENGTH];
    System.out.println("======================current:"+LENGTH+"======================");
    ull.staticTest();
    ull.nonstaticTest();
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    ull.avg();
    }
    }
    /*test static*/
    public void staticTest() {
    int i = -1 ;
    /*原谅我选择了再循环中启动线程,只是这样显得更方便一些*/
    while (i ++ < LENGTH - 1)  {
    new Use(true,i).start();
    }
    }
    /*test non-static*/
    public void nonstaticTest() {
    int i = -1 ;
    while (i ++ < LENGTH - 1) {
    new Use(false,i).start();
    }
    }
    /*average count*/
    public void avg() {
    long sta = 0,nonsta = 0;

    for (int i = 0 ; i < LENGTH; i++) {
    sta += avg_static[i];
    nonsta += avg_nonstatic[i];
    }

    System.out.println("static avg :" + sta / LENGTH);
    System.out.println("non-static avg :" + nonsta / LENGTH);
    }

    /**
     * @author qyp199312
     */
    class Use extends Thread { 

    private boolean isStatic;
    private String threadName;
    private int threadId;

    public Use(boolean b,int threadId) {
    this.isStatic = b;
    this.threadId = threadId;
    this.threadName = (b ? "[static-" : "[nonstatic-")+ threadId +"] ";
    }

    public void run () {
    if (isStatic) {
    long begin = System.currentTimeMillis();
    Method.littlelong1(threadName);
    avg_static[threadId] = (int) (System.currentTimeMillis() - begin);
    // System.out.println(threadName + avg_static[threadId] );
    } else {
    long begin = System.currentTimeMillis();
    // new Method().littlelong2(threadName);
    m.littlelong2(threadName);
    avg_nonstatic[threadId] = (int) (System.currentTimeMillis() - begin);
    // System.out.println(threadName + avg_nonstatic[threadId] );
    }
    }
    }
    }======================current:10======================
    static avg :372
    non-static avg :292
    ======================current:10======================
    static avg :356
    non-static avg :278
    ======================current:10======================
    static avg :301
    non-static avg :341
    ======================current:10======================
    static avg :397
    non-static avg :353
    ======================current:10======================
    static avg :430
    non-static avg :299
    ======================current:10======================
    static avg :373
    non-static avg :271
    ======================current:10======================
    static avg :359
    non-static avg :272
    ======================current:10======================
    static avg :376
    non-static avg :271
    ======================current:15======================
    static avg :545
    non-static avg :350
    ======================current:15======================
    static avg :606
    non-static avg :425
    ======================current:15======================
    static avg :541
    non-static avg :369
    ======================current:15======================
    static avg :565
    non-static avg :481
    ======================current:15======================
    static avg :547
    non-static avg :367
    ======================current:15======================
    static avg :521
    non-static avg :394
    ======================current:15======================
    static avg :525
    non-static avg :365
    ======================current:15======================
    static avg :534
    non-static avg :408
    ======================current:20======================
    static avg :670
    non-static avg :474
    ======================current:20======================
    static avg :676
    non-static avg :466
    ======================current:20======================
    static avg :676
    non-static avg :458
    ======================current:20======================
    static avg :683
    non-static avg :478
    ======================current:20======================
    static avg :690
    non-static avg :463
    ======================current:20======================
    static avg :708
    non-static avg :463
    ======================current:20======================
    static avg :691
    non-static avg :463
    ======================current:20======================
    static avg :690
    non-static avg :472
    ======================current:25======================
    static avg :838
    non-static avg :578
    ======================current:25======================
    static avg :934
    non-static avg :686
    ======================current:25======================
    static avg :803
    non-static avg :583
    ======================current:25======================
    static avg :1296
    non-static avg :1168
    ======================current:25======================
    static avg :823
    non-static avg :579
    ======================current:25======================
    static avg :872
    non-static avg :581
    ======================current:25======================
    static avg :911
    non-static avg :654
    ======================current:25======================
    static avg :818
    non-static avg :578
    ======================current:30======================
    static avg :956
    non-static avg :705
    ======================current:30======================
    static avg :1071
    non-static avg :768
    ======================current:30======================
    static avg :970
    non-static avg :680
    ======================current:30======================
    static avg :1052
    non-static avg :731
    ======================current:30======================
    static avg :1390
    non-static avg :1356
    ======================current:30======================
    static avg :1078
    non-static avg :855
    ======================current:30======================
    static avg :966
    non-static avg :697
    ======================current:30======================
    static avg :978
    non-static avg :696
    可能是线程数不够的缘故,我并没有测出后面的反比,我待会将线程数再翻倍试试。
      

  9.   


    本机为win7 64,服务器为centos6.3 64.
    我不是多么明白工作模式是什么意思,刚刚在本机上跑时我指定了Arguments和jre跑的过程:
    设置线程数为10:
    static avg :377
    non-static avg :281
    设置线程数为20:
    static avg :718
    non-static avg :505
    设置线程数为40:
    static avg :1544
    non-static avg :1275
    有个公式MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads不知道对不对。按照这个公式算出来和我自己测出来的jvm最大线程数是远大于当前程序新开的线程数的。
    因为内存的缘故就完全可以忽略了。
    而CPU时间片~该程序单个执行耗时约50ms。我想约20个线程(不包含其他进程,本机运行时未运行其他任务),应该不存在每个线程还需要轮询吧?(我不知道怎么查询本机的时间片长度)因为不同的工作模式对于线程和函数调用做了不同的优化。你具体可以看上去分别工作在什么模式下面。
    贴上我上面运行代码的贴图:
      

  10.   

    你所指的情况确实出现了,不过不是抛物线。
    起始情况为单个线程执行时间与线程数近似正比。等待增加到一定线程数的时候正比值就逐渐放缓了。
    只有等到需要多个时间片轮或者是内存耗尽或者是其他什么的原因的时候,执行时间大幅度上升。但这不是我们讨论的范围了。‘
    可是起始情况我仍然不是很明白(正比是怎么来的)楼上应该有提到过,是因为线程数和CPU内核(线程)数之关的关系。因为一个线程只能跑在一个CPU核上,如果线程数<CPU内核数,你新创线程,还有空的CPU内核可以分配,所以能得到提升。一旦超过,多创线程只会创造争用,增加开销。
      

  11.   


    本机为win7 64,服务器为centos6.3 64.
    我不是多么明白工作模式是什么意思,刚刚在本机上跑时我指定了Arguments和jre跑的过程:
    设置线程数为10:
    static avg :377
    non-static avg :281
    设置线程数为20:
    static avg :718
    non-static avg :505
    设置线程数为40:
    static avg :1544
    non-static avg :1275
    有个公式MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads不知道对不对。按照这个公式算出来和我自己测出来的jvm最大线程数是远大于当前程序新开的线程数的。
    因为内存的缘故就完全可以忽略了。
    而CPU时间片~该程序单个执行耗时约50ms。我想约20个线程(不包含其他进程,本机运行时未运行其他任务),应该不存在每个线程还需要轮询吧?(我不知道怎么查询本机的时间片长度)这就是工作模式,有Client VM 和Server VM。
      

  12.   


    你所指的情况确实出现了,不过不是抛物线。
    起始情况为单个线程执行时间与线程数近似正比。等待增加到一定线程数的时候正比值就逐渐放缓了。
    只有等到需要多个时间片轮或者是内存耗尽或者是其他什么的原因的时候,执行时间大幅度上升。但这不是我们讨论的范围了。‘
    可是起始情况我仍然不是很明白(正比是怎么来的)
    所谓并发是针对多核CPU的,对单个CPU都是串行的,
    比如20线程,在争取两个CPU的时间片,一个CPU在任一时刻都只能执行一个线程;
    你现在看到好像线程越多,执行时间越长,那是因为你的测试demo没有任何耗时的操作的,如读取数据库、读取文件等等,所以不能很好地体现多线程带来的好处;你可以尝试测试串行读取10个文件和并发读取看看,执行时间有没有区别。
      

  13.   


    你搞错 client vm和server vm的区别。
      

  14.   


    额。怎么一按回车就提交了。关于第4点补充一下:
    4.楼主说的第2点结论可能是因为JVM工作模式不同导致的,也可能是因为你服务器的多核CPU给线程并行执行导致的;对于楼主说的第一点结论,个人认为并不是“修改线程数,得到的时间近似正比翻倍”,也不是“不管多少个线程执行平均时间应该是近似相等的”,而是应该类似抛物线,在某一点CPU资源和JVM线程得到最合理的分配,在这之前线程数和CPU执行时间是成正比;而这之后线程数和CPU执行时间是成反比的,因为过多的线程导致CPU时间片的分配越来越激烈,内存资源可能会被耗尽,线程间频繁的上下文切换也很耗资源;

    你所指的情况确实出现了,不过不是抛物线。
    起始情况为单个线程执行时间与线程数近似正比。等待增加到一定线程数的时候正比值就逐渐放缓了。
    只有等到需要多个时间片轮或者是内存耗尽或者是其他什么的原因的时候,执行时间大幅度上升。但这不是我们讨论的范围了。‘
    可是起始情况我仍然不是很明白(正比是怎么来的)楼上应该有提到过,是因为线程数和CPU内核(线程)数之关的关系。因为一个线程只能跑在一个CPU核上,如果线程数<CPU内核数,你新创线程,还有空的CPU内核可以分配,所以能得到提升。一旦超过,多创线程只会创造争用,增加开销。
      

  15.   

    第一个问题很容易解释的:
    操作系统是分时多任务系统,同时20个线程各完成N量的工作,与同时30线程各完成N量,CPU分配得线程更多,平均完成的时间当然越长。
    举例:设每线程完成N量工作需要5单位时间,现在同一CPU分配20份去做,第二次分配30份去做,当然30份的时间长,因为其它不在运行态的线程要等得更久。楼主的逻辑错误在于,不应该取系统时间相加减,而要看该线程CPU运行时间,这样才是合理的。
    long begin = System.currentTimeMillis();
    Method.littlelong1(threadName);
    avg_static[threadId] = (int) (System.currentTimeMillis() - begin);
    不过不知道java中有无方法取得。第二个问题可能与系统有关,我的运行结果,有时多,有时少,有随机性。
    20 thead:
    static avg :1598
    non-static avg :157320 thead:
    static avg :1485
    non-static avg :144930 thread:
    static avg :1929
    non-static avg :197540 thread:
    static avg :3113
    non-static avg :3092最后说句,看来我的win7 64bit + i3 + 8G 的配置落伍了啊!!
      

  16.   

    我个人的理解,静态方法和类方法效率是非常相近的,其中的取舍不应该在于软件环境(OS,JRE等,那不是java应用程序员所能控制的),而应在于系统框架设计,忽略这一点小小性能差异吧,更灵活的设计是正道。
    像Spring框架定义singleton模式的服务类,不也是经常用吗?谁说它不好呢,非要全用静态?
    像某些Util类全是静态,用起来方便,不需要实例化。谁说它不好呢,非要全用实例方法?
      

  17.   

    ”不应该取系统时间相加减,而要看该线程CPU运行时间“  怎样才能够去线程的运行时间?
      

  18.   

    遇到一个对我来说老难的问题 真心不知道该怎么解决首先 有一张表A   字段有  编号 ,名称 ,卡号是两位的char类型 
     
    有一个页面B在进入时  显示  主要这么几部分 :
     1 学号输入栏
     2 查询按纽
     3 各种个人信息
     4 很多个多选框
     5 提交按纽
     以上中的  很多个多选框对应的内容就是 A表中的名称 
     大家可以理解成 A表是个商品表     譬如说   电脑   手机   键盘  鼠标  等等  以后会不断加入新的 数据
     
    刚进入页面B的时候,所有数据栏都是空的,  多选框显示出A表的所有名称 有多少个名称就有多少个 多选框,一个框都没有勾选。
     
    之后在 学号输入栏输入  学号 ,点击查询 ,会在C表中根据学号查出一条数据,里面有一个字段100位,用来存放 ,勾选了的商品的对应编号的。
     譬如说之前有个一条数据 ,是   学号001  姓名 李三  的数据  里面一个字段 是  M4T8  ,在后台action里 
     把M4T8  两两位切开, 也就是  M4 , T8, 这时前台B页面里 对应的  M4的 手机和 T8的 鼠标 选框就会被勾上
     
    关键是这里 以前一般的 写死的 固定的 多选框  都是一个多选框对应一个name,每个name都在form里有对应属性,通过form来在后台action传递到前台可是这次的name是不确定的  该怎么办呢