方式一:继承Thread类
新建一个类并该类声明为Thread
的子类。 这个子类应该重写run
类的方法。例如,计算大于规定值的素数的线程可以写成如下:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
然后,以下代码将创建一个线程并启动它运行:
PrimeThread p = new PrimeThread(143);
p.start();
其中start方法是Thread父类中的一个方法,该方法的目的就是创建新的线程,Java虚拟机调用此线程的run方法。
方式二:继承Runnable接口,实现run方法;这种其他风格的同一个例子如下所示:
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
然后,以下代码将创建一个线程并启动它运行:
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
其中的start方法与上述无异,都是新创建一个线程并调用run方法。
方式三:继承Callable接口,实现call方法。该新建线程的接口是在JDK1.5之后新推出的;例子如下:
class CallableTest implements Callable {
//返回结果并可能引发异常的任务。
public V call throws Exception() {
...
}
}
Callable
接口类似于Runnable ,因为它们都是为其实例可能由另一个线程执行的类设计的。 然而,Runnable
不返回结果,也不能抛出被检查的异常。
然后,以下代码将创建一个线程并启动它运行:
//创建Callable接口实现类的对象
CallableTest callableTest = new CallableTest();
//将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
FutureTask futureTask = new FutureTask(callableTest);
//将futureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
new Thread(futureTask).start();
try{
//获取Callable中call方法的返回值
//get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值
Objest obj = futureTask.get();
}catch(InterruptedException e){
e.printStackTrace();
}catch(ExecutionException e){
e.printStackTrace();
}
方式四: 创建线程池方法创建线程。JDK1.5之后,有了线程池相关的API:ExecutorService和Executors
ExecutorService:真正的线程池接口
Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
//利用Executors的方法newFixedThreadPool,该方法是创建一个可重用n个固定线程数的线程池
ExecutorService service = Executors.newFixedThreadPool(int n);
//execute方法参数只能是继承Runnable接口的实现类
service.execute(Runnable command);
//submit方法可写继承Callable和Runnable接口的实现类,大多数情况下写Callable,因为该方法有返回值与其中的call方法相对应,返回值用FutureTask接收,与方式三相同
service.submit(Callable<T> task);
//创建线程池需要手动关闭
service.shutdown();
相关文章
暂无评论...