client版比较适合桌面程序,它会做一些例如像快速初始化,懒加载这一类的事情来适应桌面程序的特点
server版则比较适合服务器程序,它做的则是一些针对服务器特点的事情,比如预加载,尤其在一些并发的处理上,它更是会做很多的优化,
比如线程共享变量的处理,它经过编译(运行)发现并没有要求某一变量对其他线程可见,它则不会将该变量同步到主存(可能永远不会)
之前在学习java并发时写过一个线程池
http://snake1987.iteye.com/blog/993112
稍微试了一下-server跟-client的区别
下面是运行结果
//-client
//55234043228
//234164019238
//-server
//3076884002
//3077230620
第一个结果是调度任务完成时间
第二个结果是完成所有任务的完成时间
很吓人的结果 近10倍
然后是今天
最近在写一个模块,并发会很高,所以打算能避免冲突则尽量让它不冲突
所以在一个全局消息队列的处理上,只在修改时加锁,在读取时则不加锁
因为消息的读取在业务上是允许延时的,所以打算不保证可见性,
因为根据文档得知cpu寄存器在一段时间后,是会将数据同步到主存的,这时自然就可见了
但会不会同步到主存呢,为了验证这个问题,写了个小测试
public static class LoopWrap { private boolean loop; public LoopWrap(boolean loop) { this.loop = loop; } public boolean isLoop() { return loop; } public void setLoop(boolean loop) { this.loop = loop; } } public static void main(String[] args) throws InterruptedException { //该变量没有保证可见性 LoopWrap loop = new LoopWrap(true); for(int i = 0;i<3;i++) { Thread t = new TestThread(loop); t.start(); } System.out.println("sleep"); Thread.sleep(10000); System.out.println("change loop"); //sleep之后改变变量为false,如果是可见的,线程应该马上输出end,如果没有,则看一下什么时候会可见 loop.setLoop(false); Thread.sleep(10000); } public static class TestThread extends Thread { private LoopWrap loop; public TestThread(LoopWrap loop) { this.loop = loop; } @Override public void run() { long count = 0; while(loop.isLoop()) { for(int i = 0;i<100;i++) { count+=i; } } System.out.println("end"); } } public static class LoopWrap { private boolean loop; public LoopWrap(boolean loop) { this.loop = loop; } public boolean isLoop() { return loop; } public void setLoop(boolean loop) { this.loop = loop; } } public static void main(String[] args) throws InterruptedException { LoopWrap loop = new LoopWrap(true); for(int i = 0;i<3;i++) { Thread t = new TestThread(loop); t.start(); } System.out.println("sleep"); Thread.sleep(10000); System.out.println("change loop"); loop.setLoop(false); Thread.sleep(10000); } public static class TestThread extends Thread { private LoopWrap loop; public TestThread(LoopWrap loop) { this.loop = loop; } @Override public void run() { long count = 0; while(loop.isLoop()) { for(int i = 0;i<100;i++) { count+=i; } } System.out.println("end"); } }
-client下是瞬间输出了end
-server下是死循环~~也就是说一直没有同步到主存了,或者说其他的线程一直只访问的是线程内缓存,也没有重新从主存中去取值
在这说一下,在开发并发相关的tx们,注意一下
1.在做压力测试的时候,记得使用hotspot的server版,否则是没有意义的
2.注意一下线程可见性的问题