问题描述
1. 全局变量num=0 两个线程同时执行以下代码 { for(int i=0;i<50;i++){ num+=1; } } 最终num值的范围是什么?2. 设计一个并发量100左右的系统 从服务器 应用 手段各个角度考虑
解决方案
第一题应该是50到100并发100的话,考虑数据库连接池,缓存,并发安全上 使用锁,队列
解决方案二:
第一题:50-100第二题:上网搜 一大把
解决方案三:
第一题应该是100.无论线程什么时候阻塞,两个线程都会正常执行完,相当于执行两次+50第二题考虑连接池,重叠IO,端口重用等
解决方案四:
1. num+=1这个操作不具有原子性,并且mun至少被计算一次后泻入内存,因此从理论上讲,值的范围是1-1002. 这个要说的比较多,总的来说就是降低级别,少用锁,提高程序并发能力,话说回来100并发应该还可以,没那么多需要考虑的
解决方案五:
引用+ 和 =是两个操作吧 , 不会有这种情况: 线程1的+操作正在进行, 线程2的循环结束, 线程1才开始执行=操作吗。 还有int变量如果不加volatile关键字, 变量貌似是存放在各自的寄存器缓存里的, 而不一定什么时候才赋值给全局变量。。 有没有可能发生 线程2num赋值为50 而线程1重新把num变为1呢。。 或者线程2执行到49时, 线程1赋值给全局变量1 , 此时线程2拿到的num又变为1了?其实差不多就是这样子的。。。。所以答案应该是50~100
解决方案六:
用scala写的,都是用的java的类库,你改成java代码就可以了,结果50-100.object SzStudy extends App { import java.util.LinkedList import java.util.concurrent._ var num = 0 val pool = Executors.newFixedThreadPool(2) val calls = new LinkedList[Callable[Unit]](); val call = new Callable[Unit] { def call() { for (i <- 0 to 49) { num += 1 } } } calls.addLast(call) calls.addLast(call) val fa = pool.invokeAll(calls) val iter=fa.iterator //阻塞主线程,等两个子线程运行完 while(iter.hasNext){ iter.next.get() } println(num)}
解决方案七:
要看主子线程的阻塞程度了。 如zhangzehao 所写,两个子线处理速度足够快,那结构就是100如果子线程阻塞程度高,主线程没有阻塞那 也就是0或是1总所有情况取之范围应该会在0-100之间
解决方案八:
看了回答,同志们真心不看题啊,第一题问num最后的值是多少,不是让写程序。个人感觉是50~100,测实测第二题:并发量100该如何控控制,求教高手!这个真心不懂
解决方案:
public static void main(String[] args){Thread thread1 = new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<50;i++){num++;System.out.println(num);}}});Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<50;i++){num++;System.out.println(num);}}});thread1.start();thread2.start();}
解决方案:
上面那个有点问题,保证线程2先拿到;这里最后的结果就是1,,但是对于计算机来说num+=1; 这里执行的时间是一样多的,所以并不会出现线程1执行完了,线程2才执行了1步这种情况static int num =0;public static void c(){Thread t1 = new Thread(){@Overridepublic void run() {try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}for(int i=0;i<50;i++)num+=1;}}; Thread t2=new Thread(){@Overridepublic void run() {try { //线程2先拿到num,然后阻塞住sleep(999);for(int i=0;i<50;i++){int temp = num;if(i==0){sleep(1000);temp+=1;num=temp;}}} catch (InterruptedException e) {e.printStackTrace();}}};t1.start();t2.start();}public static void main(String[] args) {c();try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(num);}
解决方案:
就算阻塞了它还是要循环的啊线程2这个时间很慢,按照你说的模拟了下static int num =0;public static void c(){Thread t1 = new Thread(){@Overridepublic void run() {try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}for(int i=0;i<50;i++)num+=1;}}; Thread t2=new Thread(){@Overridepublic void run() {try {sleep(1000);for(int i=0;i<50;i++){int temp = num;if(i==0){sleep(1000);temp+=1;num=temp;}}} catch (InterruptedException e) {e.printStackTrace();}}};t1.start();t2.start();}public static void main(String[] args) {c();try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(num);}
解决方案:
tomcat 本身 默认支持的并发为200.配和连接池,完全给解决 第一个 50