1.继承thread类
public class Thread implements Runnable
从上面的源代码可以发现,thread类实现了runnable接口,他们之间是多态的关系。首先来看一下它的实现方式,继承thread类,重写run方法。
public class LiftOff {
public static void main(String[] args) {
// TODO Auto-generated method stub
Mythread mythread=new Mythread();
mythread.start();
}
}
class Mythread extends Thread{//继承thread类
public void run(){//重写run方法
super.run();
System.out.println("my thread");
}
}
但是因为java单继承的特性,所以这种方法不常用,具有局限性。
2.实现runnable接口
线程可以驱动任务,任务可以用实现runnable接口来完成。即实现runnable接口并且编写run方法。主函数中创建thread类,并将实现runnable的类作为参数传递给他,开启线程即可。
class LiftUp implements Runnable{
protected int countDown=10;
private static int taskcount=0;
private final int id=taskcount++;
public LiftUp(int countDown){
this.countDown=countDown;
}
public String status(){
return "#"+id+"("+(countDown>0?countDown:"LiftUp")+").";//模拟火箭起飞,倒计时小于0就起飞
}
public void run(){
while(countDown-->0){
System.out.println(status());
}
}
}
3.使用excutorservie,callable,future实现有返回结果的(见下一篇博客详解)
初学多线程的时候,认为只有两种实现多线程的方式,都是没有返回结果的,在看java编程思想的时候才发现还有一种使用executor的方式,而它也是java se 5/6启动任务的优选方法。
1.使用executor
将实现runnable接口的对象传递给execute()方法,CachedThreadPool将为每个任务都创建一个线程。
public class LiftOff {
public static void main(String[] args) {
ExecutorService exec=Executors.newCachedThreadPool();
//ExecutorService exec=Executors.newFixedThreadPool(5);有限的线程集
//FixedThreadPool一次性预先执行代价高昂的线程分配,限制了线程的数量,节省时间和资源
//singleThreadExecutor就是线程为1的FixedThreadPool。如果像它提交了多个任务,那么
//这些任务会排队,每个任务都会在下一个任务开始之前运行结束,所有的任务使用相同的线程
for(int i=0;i<5;i++){
exec.execute(new LiftUp());
}
exec.shutdown();
}
}
2.从任务中产生返回值
Runnable是执行工作的独立任务,但是它不返回任何值。若要返回值的话,那么可以实现callable接口。它是一种具有类型参数的泛型,它的类型参数表示的是从方法call()中返回的值,必须使用ExecutorService。submit()方法来调用它。
public class CallableDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService exec=Executors.newCachedThreadPool();
ArrayList<Future<String>> results=new ArrayList<Future<String>>();
for(int i=0;i<10;i++){
results.add(exec.submit(new TaskWithResult(i)));//submit方法会产生future对象
}
for(Future<String> fs:results){
try {
System.out.println(fs.get());
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(e);
} catch (ExecutionException e) {
e.printStackTrace();
System.out.println(e);
}finally{
exec.shutdown();
}
}
}
}
class TaskWithResult implements Callable<String>{
private int id;
public TaskWithResult(int id){
this.id=id;
}
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "result of TaskWithResult"+id;
}
}
submit方法会产生一个future对象,使用callable返回结果的特定类型进行了参数化。可以使用isdone()方法来查询future是否完成。任务完成时,具有结果,可以使用get()方法来获取这个结果。