一 为什么需要多线程控制
看代码:
package mutithread;public class ThreadTest { PRivate static int count=0; public static void addCount(){ for(int i=0;i<100;i++){ ++count; } } public static void main(String[] args){ for(int i=0;i<10;i++){ new Thread(new Runnable() { public void run() { addCount(); System.out.println("name="+Thread.currentThread().getName()+";count="+count); } }).start(); } System.out.println("name="+Thread.currentThread().getName()+";count="+count); }}输出结果为:name=main;count=0name=Thread-1;count=100name=Thread-5;count=200name=Thread-9;count=300name=Thread-3;count=400name=Thread-7;count=500name=Thread-0;count=700name=Thread-4;count=700name=Thread-8;count=800name=Thread-2;count=900name=Thread-6;count=1000
疑似一切正常,唯一可疑的一点是main线程居然最先结束了,所以让main线程先sleep()一下,等待其它线程执行完,同时其它线程也sleep()一下,目的是为了加大错误发生的概率,从而说明多线程下上述代码有问题,需要控制:
public static void main(String[] args) throws InterruptedException{ for(int i=0;i<10;i++){ new Thread(new Runnable() { public void run() { try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } addCount(); System.out.println("name="+Thread.currentThread().getName()+";count="+count); } }).start(); } Thread.sleep(2000); System.out.println("name="+Thread.currentThread().getName()+";count="+count); }输出如下:name=Thread-3;count=104name=Thread-6;count=204name=Thread-7;count=304name=Thread-0;count=404name=Thread-4;count=504name=Thread-8;count=604name=Thread-2;count=104name=Thread-1;count=704name=Thread-5;count=904name=Thread-9;count=904name=main;count=904
怪异的事情发生了,都是并发惹得祸,出错的原因是多个线程共享count变量。
二 如何解决上述问题java提供了多种措施,最简单的方式使在操作共享变量的方法上加synchronized关键字:
public static synchronized void addCount(){ for(int i=0;i<100;i++){ ++count; } }然后不管你如何执行,最后count值都为1000。三 synchronized关键字是如何做到的见下一篇博客。
四 共享变量是如何被使用的分析JVM内存模型可知,每个线程有自己的工作区,对于共享变量,线程每次读取的是工作内存中共享变量的副本,写入的时候也直接修改工作内存中副本的值,然后在某个时间点上再将工作内存与主内存中的值进行同步。于是,问题来了:如果线程1对某个变量进行了修改,线程2却不知道。然后又各自将修改后的副本值同步到主内存,必然就出错了。
新闻热点
疑难解答