解决方案 »
- java.sql.Date 和java.util.Date 怎么互相转换?
- 一个改变字体大小的applet的程序
- 高分急问:线性规划问题怎么解?有没有现成代码?
- eclipse设计gui的奇怪问题(详情请进),请问怎么解决
- 关于jtable的几个问题
- 在java中如何实现弹出dos窗口,我的是win2000
- 不用vector和arraylist,可以怎样动态扩展数组的边界?
- 类路径是什么意思
- sos.........
- DWRSession过期拦截,通过继承实现 DWRSessionServiceextendsDefaultRemoter 登陆时如何绕过这个验证
- java调用方法的参数类型匹配为何会不一致?
- 求教~~~关于类加载机制的问题
服务器 windows?linux? 32bit?64bit ?
1.就像楼上说的工作模式会导致性能的差别;
2.你服务器和本地的配置差别比较大,就cpu而言一个是双核的,一个是八核的,内存应该也有差别吧。这样的无法验证你认为的“不管多少个线程执行平均时间应该是近似相等的”,应该同一环境下测试;
3.如果你是在同一环境下测试来验证验证你认为的“不管多少个线程执行平均时间应该是近似相等的”,需要注意当前JVM的CPU、内存、线程等实用情况,比如会不会超过CPU或JVM限制的最大线程数了?是不是内存资源耗尽导致线程分配失败?CPU使用率过高导致无法给新的线程分配时间片?等等;可以实用Jconsole来观察,如下图:4.你说的第2点结论可能是因为JVM工作模式不同导致的;
4.楼主说的第2点结论可能是因为JVM工作模式不同导致的,也可能是因为你服务器的多核CPU给线程并行执行导致的;对于楼主说的第一点结论,个人认为并不是“修改线程数,得到的时间近似正比翻倍”,也不是“不管多少个线程执行平均时间应该是近似相等的”,而是应该类似抛物线,在某一点CPU资源和JVM线程得到最合理的分配,在这之前线程数和CPU执行时间是成正比;而这之后线程数和CPU执行时间是成反比的,因为过多的线程导致CPU时间片的分配越来越激烈,内存资源可能会被耗尽,线程间频繁的上下文切换也很耗资源;
for(i =0;i<LENGTH;i++){
new Use(true, i).run1();
}run函数改名做run1修改Length对时间的消耗从此没有影响了。
本机为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个线程(不包含其他进程,本机运行时未运行其他任务),应该不存在每个线程还需要轮询吧?(我不知道怎么查询本机的时间片长度)
本机为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个线程(不包含其他进程,本机运行时未运行其他任务),应该不存在每个线程还需要轮询吧?(我不知道怎么查询本机的时间片长度)因为不同的工作模式对于线程和函数调用做了不同的优化。你具体可以看上去分别工作在什么模式下面。
新代码: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
可能是线程数不够的缘故,我并没有测出后面的反比,我待会将线程数再翻倍试试。
本机为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个线程(不包含其他进程,本机运行时未运行其他任务),应该不存在每个线程还需要轮询吧?(我不知道怎么查询本机的时间片长度)因为不同的工作模式对于线程和函数调用做了不同的优化。你具体可以看上去分别工作在什么模式下面。
贴上我上面运行代码的贴图:
起始情况为单个线程执行时间与线程数近似正比。等待增加到一定线程数的时候正比值就逐渐放缓了。
只有等到需要多个时间片轮或者是内存耗尽或者是其他什么的原因的时候,执行时间大幅度上升。但这不是我们讨论的范围了。‘
可是起始情况我仍然不是很明白(正比是怎么来的)楼上应该有提到过,是因为线程数和CPU内核(线程)数之关的关系。因为一个线程只能跑在一个CPU核上,如果线程数<CPU内核数,你新创线程,还有空的CPU内核可以分配,所以能得到提升。一旦超过,多创线程只会创造争用,增加开销。
本机为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。
你所指的情况确实出现了,不过不是抛物线。
起始情况为单个线程执行时间与线程数近似正比。等待增加到一定线程数的时候正比值就逐渐放缓了。
只有等到需要多个时间片轮或者是内存耗尽或者是其他什么的原因的时候,执行时间大幅度上升。但这不是我们讨论的范围了。‘
可是起始情况我仍然不是很明白(正比是怎么来的)
所谓并发是针对多核CPU的,对单个CPU都是串行的,
比如20线程,在争取两个CPU的时间片,一个CPU在任一时刻都只能执行一个线程;
你现在看到好像线程越多,执行时间越长,那是因为你的测试demo没有任何耗时的操作的,如读取数据库、读取文件等等,所以不能很好地体现多线程带来的好处;你可以尝试测试串行读取10个文件和并发读取看看,执行时间有没有区别。
你搞错 client vm和server vm的区别。
额。怎么一按回车就提交了。关于第4点补充一下:
4.楼主说的第2点结论可能是因为JVM工作模式不同导致的,也可能是因为你服务器的多核CPU给线程并行执行导致的;对于楼主说的第一点结论,个人认为并不是“修改线程数,得到的时间近似正比翻倍”,也不是“不管多少个线程执行平均时间应该是近似相等的”,而是应该类似抛物线,在某一点CPU资源和JVM线程得到最合理的分配,在这之前线程数和CPU执行时间是成正比;而这之后线程数和CPU执行时间是成反比的,因为过多的线程导致CPU时间片的分配越来越激烈,内存资源可能会被耗尽,线程间频繁的上下文切换也很耗资源;
你所指的情况确实出现了,不过不是抛物线。
起始情况为单个线程执行时间与线程数近似正比。等待增加到一定线程数的时候正比值就逐渐放缓了。
只有等到需要多个时间片轮或者是内存耗尽或者是其他什么的原因的时候,执行时间大幅度上升。但这不是我们讨论的范围了。‘
可是起始情况我仍然不是很明白(正比是怎么来的)楼上应该有提到过,是因为线程数和CPU内核(线程)数之关的关系。因为一个线程只能跑在一个CPU核上,如果线程数<CPU内核数,你新创线程,还有空的CPU内核可以分配,所以能得到提升。一旦超过,多创线程只会创造争用,增加开销。
操作系统是分时多任务系统,同时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 的配置落伍了啊!!
像Spring框架定义singleton模式的服务类,不也是经常用吗?谁说它不好呢,非要全用静态?
像某些Util类全是静态,用起来方便,不需要实例化。谁说它不好呢,非要全用实例方法?
有一个页面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是不确定的 该怎么办呢