这里主要总结一下Java中有关多线程的内容,Java中多线程的内容很重要的,只是本人学识尚浅,斌哥讲完了课之后又查阅了很多资料才算是搞懂了一些。
首先我们应该知道的是Java中实现多线程有两种实现方法,第一种是extends Thread,第二种是implements Runnable,关于这两种的区别和用法会在下面讲到,我们先看着两种实现方式的代码:
public class Lisa extends Thread{
private String name;
public Lisa(String name){
this.name = name;
}
public void run(){
System.out.println("运行"+name);
}
}
主函数中调用
public static void main(String[] args){
Lisa lisa1 = new Lisa("aaa");
Lisa lisa2 = new Lisa("bbb");
Lisa lisa3 = new Lisa("ccc");
Lisa lisa4 = new Lisa("ddd");
Lisa lisa5 = new Lisa("eee");
lisa1.run();
lisa2.run();
lisa3.run();
lisa4.run();
lisa5.run();
}
运行结果:
在这里看到是按顺序输出的,说明调用方法不对,不能调用run方法,应该调用start方法,调用如下:
public static void main(String[] args){
Lisa lisa1 = new Lisa("aaa");
Lisa lisa2 = new Lisa("bbb");
Lisa lisa3 = new Lisa("ccc");
Lisa lisa4 = new Lisa("ddd");
Lisa lisa5 = new Lisa("eee");
lisa1.start();
lisa2.start();
lisa3.start();
lisa4.start();
lisa5.start();
}
这样的话运行结果如下:
在这里就不会按照调用顺序输出了,而且每次的结果输出顺序都会不同,因为需要cpu来调度资源,但是调用start还是会执行run方法主体,为什么不能直接调用run方法呢,我们可以打开start方法的源代码看一下:
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
注意在最后一行调用了start0的方法,而且他是native的,即需要本地化的支持,调用了操作系统的函数,我的理解是因为 多线程的实现需要本地操作系统的支持。
我们再来看实现runnable的方式:
public static void main(String[] args){
Lisa lisa1 = new Lisa("aaa");
Lisa lisa2 = new Lisa("bbb");
Lisa lisa3 = new Lisa("ccc");
Lisa lisa4 = new Lisa("ddd");
Lisa lisa5 = new Lisa("eee");
Thread demo1 = new Thread(lisa1);
Thread demo2 = new Thread(lisa2);
Thread demo3 = new Thread(lisa3);
Thread demo4 = new Thread(lisa4);
Thread demo5 = new Thread(lisa5);
demo1.start();
demo2.start();
demo3.start();
demo4.start();
demo5.start();
}
运行结果如下:
我们可以看到运行的顺序也不是按照调用顺序来的,那我们到底选择继承Thread还是实现Runnable呢?
首先,我们可以看下Thread的源代码:
class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
这里我们可以看到Thread也是实现Runnable的,即Thread中的run方法继承自Runnable接口,即Thread和Runnable都实现了run方法。关于线程这块还有很多内容,先总结到这里,权当笔记,还会继续完善。