java 多线程
2017-09-02 21:52 雄风狂飙 阅读(207) 评论(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
执行多次都是一个结果。