java 多线程
2017-09-02 21:52 雄风狂飙 阅读(217) 评论(0) 收藏 举报最近工作上有个地方需要用到多线程,是用C++的,下午加班改代码,但是网络出现问题,连不了主机,于是在java上面测试并回顾了一些知识。记录一下。
1.多线程的类helloworld。
在thread类中持有一个实现了runnable接口的实例化对象,然后thread类run的时候,会调用runnable的run。这一点在很多入门的书籍中都有介绍,没必要赘述,但是为什么要这么写,这里稍微把java中的代码粘贴一下。代码如下:
Thread类有一个接受runnable实现对象的构造函数,
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
init函数中最重要的一段代码是:this.target = target;
即给Thread的target这个变量set成了传进来的target。当Thread的run执行的时候,实际上会调用target的run函数。在源码中是这么说的“/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.”
也就是Thread的start执行以后调用Thread的run方法。而run方法会调用target的run方法,代码如下:
public void run() {
if (target != null) {
target.run();
}
}
测试的Thread主类如下:
public class TestThread {
static int threadNum = 10;
static int maxloop = 10000;
public static void main(String arg[])
{
Thread threads[] = new Thread[100];
for( int i = 0; i <= threadNum ; ++i)
{
String threadName = "Thread " + Integer.valueOf(i);
threads[i] = new Thread(new TestRunable(threadName,maxloop));
threads[i].start();
}
for( int i = 0; i <= threadNum ; ++i)
{
try {
threads[i].join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Integer.valueOf(i) + "thread done.");
}
System.out.println( "count==" + Integer.valueOf( Global.count ) );
}
}
这里用到了一个全局变量Global.count,其目的在下面第三点说明。
2.测试join函数。join函数就是等待自身的函数,其效果如下:
8thread done.
。。。
Thread 9 9999
Thread 9 10000
9thread done.
10thread done.
也就是在线程8结束以后,线程9还未结束,那么主线程就一直等待线程9结束以后,再等待线程10结束,然后再继续往下执行。
3.测试线程操作统一个未上锁的变量的情况。
这里先把实现了runnable接口的类也贴出来。
package test;
public class TestRunable implements Runnable {
private
int mi;
String ms;
int mmaxloop;
@Override
public void run() {
// TODO Auto-generated method stub
for( int i = 0;i<=mmaxloop*10;++i )
{
System.out.println( ms + " " + Integer.valueOf(mi));
++mi;
++Global.count;
}
}
TestRunable(String ss,int maxLoop)
{
this.mi = 0;
this.ms = ss;
mmaxloop = maxLoop;
}
}
此外,还有全局变量的类也一道贴出来:
public class Global {
public
static int count = 0;
}
其结果是每次测试的结果,对全局变量的打印数字都不一致。
比如,某次执行的结果是(对源码中的某些数字可能进行一些放大或者缩小,不影响其效果):
7thread done.
8thread done.
9thread done.
10thread done.
count==1100010
另外一次执行的结果是:
7thread done.
8thread done.
9thread done.
10thread done.
count==1100011
4.互斥实现。
testRunnable类的代码修改为:
for( int i = 0;i<=mmaxloop*100;++i )
{
System.out.println( ms + " " + Integer.valueOf(mi));
++mi;
synchronized(this)
{
++Global.count;
}
}
再执行多次,查看Global.count结果,都是一个值吗?
第一次:
count==1100009
第二次:
8thread done.
9thread done.
10thread done.
count==1100011
于是,发现根本就没有完成互斥。
5.原来互斥是需要针对一个对象的。经过修改以后的代码如下,就可以完成互斥了。
static int threadNum = 10;
static int maxloop = 1000;
public static void main(String arg[]) {
Thread threads[] = new Thread[100];
System.out.println("ssssssssssss");
Global global = new Global();
String threadName = "same";
TestRunnable testRunnable = new TestRunnable(threadName, maxloop,
global);
for (int i = 0; i <= threadNum; ++i) {
// String threadName = "Thread " + Integer.valueOf(i);
threads[i] = new Thread(testRunnable);
threads[i].start();
}
for (int i = 0; i <= threadNum; ++i) {
try {
threads[i].join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println(Integer.valueOf(i) + "thread done. mi==" +
// Integer.valueOf(threads[i].g));
System.out.println(Integer.valueOf(i)
+ "thread done. global.count=="
+ Integer.valueOf(global.count));
}
System.out.println("count==" + Integer.valueOf(global.count));
}
results:
count==1100000
执行多次都是一个结果。
浙公网安备 33010602011771号