首页 > 学院 > 开发设计 > 正文

多线程——理论基础

2019-11-06 06:27:25
字体:
来源:转载
供稿:网友

一 为什么需要多线程控制

看代码:

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却不知道。然后又各自将修改后的副本值同步到主内存,必然就出错了。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表