一、继承thread类
实现方式很简单,只需要创建一个类去继承thread类然后重写run方法,在main方法中调用该类实例对象的start方法即可实现多线程并发。代码:
public class mythread extends thread { @override public void run(){ super.run(); system.out.println("执行子线程..."); }}
测试用例:
public class test { public static void main(string[] args) { mythread mythread = new mythread(); mythread.start(); system.out.println("主线程..."); }}
运行结果:
当然,这里的结果不代表线程的执行顺序,线程是并发执行的,如果多运行几次,打印顺序可能会不一样。多线程的运行过程中,cpu是以不确定的方式去执行线程的,故运行结果与代码的执行顺序或者调用顺序无关,运行结果也可能不一样。
免费视频教程推荐:java学习视频
这里还有一个需要注意的点就是main方法中应该调用的是mythread的start方法,而不是run()方法。调用start()方法是告诉cpu此线程已经准备就绪可以执行,进而系统有时间就会来执行其run()方法。
而直接调用run()方法,则不是异步执行,而是等同于调用函数般按顺序同步执行,这就失去了多线程的意义了。
二、实现runnable接口
这种方式的实现也很简单,就是把继承thread类改为实现runnable接口。代码如下:
public class myrunnable implements runnable { @override public void run() { system.out.println("执行子线程..."); }}
测试用例:
public class test { public static void main(string[] args) { runnable runnable = new myrunnable(); thread thread = new thread(runnable); thread.start(); system.out.println("主线程运行结束!"); }}
运行结果:
运行结果没啥好说的,这里main中可以看到真正创建新线程还是通过thread创建:
thread thread = new thread(runnable);
这一步thread类的作用就是把run()方法包装成线程执行体,然后依然通过start去告诉系统这个线程已经准备好了可以安排执行。
三、使用callable和future创建线程
上面的两种方式都有这两个问题:
1、无法获取子线程的返回值;
2、run方法不可以抛出异常。
为了解决这两个问题,我们就需要用到callable这个接口了。说到接口,上面的runnable接口实现类实例是作为thread类的构造函数的参数传入的,之后通过thread的start执行run方法中的内容。但是callable并不是runnable的子接口,是个全新的接口,它的实例不能直接传入给thread构造,所以需要另一个接口来转换一下。
java5提供了future接口来代表callable接口里call()方法的返回值,并为future接口提供了一个实现类futuretask,该实现类的继承关系如图所示:
可以看到,该实现类不仅实现了future接口,还实现了runnable接口,所以可以直接传给thread构造函数。
而关于futuretask的构造函数如下:
所以这里面其实就是要比上一个方法再多一个转换过程,最终一样是通过thread的start来创建新线程。有了这个思路,代码就很容易理解了:
import java.util.concurrent.callable;public class mycallable implements callable { int i = 0; @override public object call() throws exception { system.out.println(thread.currentthread().getname()+" i的值:"+ i); return i++; //call方法可以有返回值 }}
测试:
import java.util.concurrent.callable;import java.util.concurrent.futuretask;public class test { public static void main(string[] args) { callable callable = new mycallable(); for (int i = 0; i < 10; i++) { futuretask task = new futuretask(callable); new thread(task,"子线程"+ i).start(); try { //获取子线程的返回值 system.out.println("子线程返回值:"+task.get() + "\n"); } catch (exception e) { e.printstacktrace(); } } }}
执行结果(部分):
相关文章教程推荐:java入门程序
以上就是java中实现多线程的几种方式的详细内容。
