java——线程(Thread,Runnable,Callable,Future)
在java中,编写多线程程序,主要有两种不同的方法
1. 继承类java.lang.Thread,然后覆盖掉run()方法就可以了,把希望运行的程序都写在run()方法中
2. 通过实现Runnable接口来编写线程,覆盖掉Runnable接口中的run()方法
public interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }
上面的代码就是接口Runnable,其实Runnalbe只是定义了一个简单的抽象函数。
public class Thread implements Runnable { }
Thread是一个实现了接口Runnable的类,类中封装了很多的常用函数。因为java中并不支持多重继承,因此有些时候需要通过实现接口Runnable来编写多线程程序。
上图所示是java中线程的一些状态(图片来源:http://www.cnblogs.com/dolphin0520/p/3920357.html)。
示例1:继承Thread类
public class MyThread { private static int j=0; class ThreadTest extends Thread{ private int i; private int time; public ThreadTest(int i,int time){ this.i=i; this.time = time; } public void run(){ while(true){ try{ Thread.sleep(time); }catch(InterruptedException e){ e.printStackTrace(); } j++; System.out.println("Thread"+i+": "+j); } } } public static void main(String[] args) { // TODO Auto-generated method stub MyThread mt = new MyThread(); ThreadTest t1 = mt.new ThreadTest(1,1000); ThreadTest t2 = mt.new ThreadTest(2,2300); ThreadTest t3 = mt.new ThreadTest(3,3500); ThreadTest t4 = mt.new ThreadTest(4,2700); t1.start(); t2.start(); t3.start(); t4.start(); } }
示例2:实现接口
public class ThreadRunnable { private static int j=0; public static void main(String[] args){ new Thread(new Runnable(){ public void run(){ while(true){ try{ Thread.sleep(1000); //休眠1000毫秒 }catch(InterruptedException e){ e.printStackTrace(); } j++; System.out.println("Thread1:"+j); } } }).start(); new Thread(new Runnable(){ public void run(){ while(true){ try{ Thread.sleep(1000); //休眠1000毫秒 }catch(InterruptedException e){ e.printStackTrace(); } j++; System.out.println("Thread2:"+j); } } }).start(); new Thread(new Runnable(){ public void run(){ while(true){ try{ Thread.sleep(1000); //休眠1000毫秒 }catch(InterruptedException e){ e.printStackTrace(); } j--; System.out.println("Thread3:"+j); } } }).start(); new Thread(new Runnable(){ public void run(){ while(true){ try{ Thread.sleep(1000); //休眠1000毫秒 }catch(InterruptedException e){ e.printStackTrace(); } j--; System.out.println("Thread4:"+j); } } }).start(); } }
有返回值的线程
在java 5 之前,线程都是没有返回值的,而Callable的出现使线程也可以返回一个结果了。
import java.util.concurrent.Callable;
上面显示的是Callable所在的包,Callable的接口代码如下
@FunctionalInterface public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
首先需要新建一个类,实现Callable接口
package threadOperation;
import java.util.concurrent.Callable;
public class MyCallable implements Callable{
private String id;
MyCallable(String id){
this.id = id;
}
@Override
public Object call() throws Exception {
// TODO Auto-generated method stub
return "this is the test of: "+id;
}
}
之后建立一个类,来测试MyCallable类的返回值
package threadOperation; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class CallableTest { public static void main(String[] args) throws InterruptedException, ExecutionException { // TODO Auto-generated method stub ExecutorService pool = Executors.newFixedThreadPool(3); //thread pool Callable c1 = new MyCallable("first thread"); Callable c2 = new MyCallable("second thread"); Callable c3 = new MyCallable("third thread"); Future f1 = pool.submit(c1); //提交线程池执行 Future f2 = pool.submit(c2); Future f3 = pool.submit(c3); System.out.println(f1.get().toString()); System.out.println(f2.get().toString()); System.out.println(f3.get().toString()); } }
这里面用到了线程池和Future这个接口,Future接口可以通过get操作来返回一个泛型的类