Java实现多线程的方式有两种,一是继承Thread类,二是实现Runnable接口。
1、继承Thread类
新建一个类,继承Thread类并重写run()方法,示例代码如下:
package org.mole.xc;
public class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
}
public void run(){
for(int i=0;i<10;i++){
System.out.println("MyThread:"+this.name+",i="+i);
}
}
}
这时在测试类中实例化MyThread类,并调用run()方法,代码和运行结果如下:
package org.mole.xc;
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread mt1 = new MyThread("线程1");
MyThread mt2 = new MyThread("线程2");
mt1.start();
mt2.start();
}
}
由运行结果可以看出,此时执行完一个对象再执行另一个对象,并没有实现交互。从JDK的文档中发现,一旦调用start()方法,则会根据JVM调用run()方法,通过start()方法启动的线程有什么不同,代码和结果如下:
package org.mole.xc;
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread mt1 = new MyThread("线程1");
MyThread mt2 = new MyThread("线程2");
mt1.start();
mt2.start();
}
}
此时实现了真正意义上的交互,为什么使用start()方法才可以完成真正的交互呢?找到Thread类中的start()方法:
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threwa Throwable then
it will be passed up the callstack */
}
}
}
private native void start0();
在操作系统中,通过低层来实现CPU的调度,多线程中进行CPU资源抢占也就是实现调度,必须通过低层来实现。在java中通过native 关键字才能实现低层函数,在start()方法中,系统自动调用run()方法,所以若想实现多线程,必须使用start()方法来启动线程。2、实现Runnable接口
因为Java的单继承机制,在实际开发中很少使用Thread类,而是通过Runnable接口完成。
public abstract interface java.lang.Runnable {
// Method descriptor #1 ()V
public abstract void run();
}
一个类只要实现了此接口,并重写run()方法就能完成。
package org.mole.xc;
public class RunnableDemo1 implements Runnable {
private String name;
public RunnableDemo1(String name) {
this.name = name;
}
public void run() {
for(int i =0;i<10;i++){
System.out.println("Runnable线程:"+this.name+",i="+i);
}
}
public static void main(String args[]){
RunnableDemo1 r1 = new RunnableDemo1("线程1");
RunnableDemo1 r2 = new RunnableDemo1("线程2");
r1.run();
r2.run();
}
}
此时的执行结果仍为先执行一个对象在执行一个对象。
因为并未执行start()方法,Runnable子类中只实现了run()方法,并未有start()方法。实际上,也只有Thread类才有start()方法,Thread类中有如下构造方法:
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
此构造方法接收Runnable 子类的实例,也就是说,通过Thread类可以启动Runnable 子类的多线程,代码和执行结果如下:
package org.mole.xc;
public class RunnableDemo1 implements Runnable {
private String name;
public RunnableDemo1(String name) {
this.name = name;
}
public void run() {
for(int i =0;i<10;i++){
System.out.println("Runnable线程:"+this.name+",i="+i);
}
}
public static void main(String args[]){
RunnableDemo1 r1 = new RunnableDemo1("线程1");
RunnableDemo1 r2 = new RunnableDemo1("线程2");
new Thread(r1).start();
new Thread(r2).start();
}
}
文中思想来自魔乐科技