创建线程的方式

来源:互联网 发布:软件定制开发流程 编辑:程序博客网 时间:2024/05/29 12:09

实现Runnable接口创建线程类:
实现Runnable接口创建并启动多线程的步骤:
*定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
*创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thraed对象才是真正的线程对象。
//创建Runnable实现类的对象
SecondThraed st =new SecondThraed();

//以Runnable实现类的对象来作为该Thraed的target来创建Thraed对象,即线程对象
new Thraed(st);

//也可以在创建Thread对象时为指定target和新线程的名字
new Thraed(st,”新线程1”);

*调用线程对象的start()方法来启动该线程。

//程序示例:

public class SecondThread implements Runnable{     private  int  i;//run方法同样是线程执行体     @Override     public void run() {           // TODO Auto-generated method stub           for( ;  i<100;i++){                //当线程实现Runnable接口时,如果想获取当前线程,只能用Thraed.currentThraed()方法                System.out.println(Thread.currentThread().getName()+ "" +i);           }     }     public static void main(String[] args) {           for(int i=0;i<100;i++){                System.out.println(Thread.currentThread().getName()+""+i);                if(i == 20){                     SecondThread   st=new SecondThread();                     //通过new  Thread(target,name)方法创建新线程                     new  Thread(st,"新线程1").start();                     new  Thread(st,"新线程2").start();;                }           }     }}

Runnable接口是函数式接口,可以使用lamdba表达式创建Runnable对象。
采用Runnable接口的方式创建的多个线程可以共享线程类的实例变量。
——————————————————————————————————————

使用Callable和Future创建线程:
从Java5开始,Java提供了Callable接口,Callable接口里提供了一个call()方法可以作为线程执行体,但call()方法比run()方法功能更强大:
**call()方法可以有返回值
**call()方法可以声明抛出异常。
Java5提供了Future接口来代表Callable 接口里call()方法的返回值,并未Future接口提供了一个FutureTask实现类,该实现类实现了Future接口,并实现了Runnable接口–可以作为Thraed类的target.
在Future接口里定义了以下公共方法来控制它关联的Callable任务
boolean cancel(boolean mayInterruptIfRunning) 试图取消该该Future里关联的Callable任务
V get() 返回Callable任务里call()方法的返回值,调用该方法将导致程序阻塞,必须等到子线程结束后才会获得返回值。
V get(long timeout,TimeUnit unit) 返回Callable任务里call()方法的返回值。该方法让程序最多阻塞timeout和unit指定的时间。如果经过指定时间后Callable任务依然没有返回值,将会抛出TimeoutException异常。
boolean isCancelled() 如果在Callable()任务正常完成前被 取消,则返回true
boolean iSDone() 如果Callable任务已经完成,则返回true。

//Callable接口有泛型限制,Callable接口里的泛型形参类型与call()方法返回值类型相同,而且Callable接口是函数式接口,可以直接用lambda表达式来创建Callable对象。

————————————
创建并且启动有返回值的线程步骤如下:

**创建Callable对象的实现类,并实现call()方法,该call()方法将作为线程执行体,且有返回值,再创建Callable实现类的实例。从Java8开始,可以直接使用lambda表达式创建Callable对象
*使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法返回值。
*使用FutureTask对象作为Thread对象的taget创建并启动新的线程。
调用FutureTask对象的get()方法来获得子线程结束后的返回值。

//程序实例:

import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class ThirdThread {     public static void main(String[] args) {           //创建Callable对象           ThirdThread  rt=new  ThirdThread();           //先使用lambda表达式创建Callable<Integer>对象使用FutureTask来包装Callable对象           FutureTask<Integer>  task=new FutureTask<Integer>  ((Callable<Integer>) () ->{                int  i=0;                for(;  i<100;i++){                     System.out.println(Thread.currentThread().getName()+"循环变量i的值"+i);                }                //call()方法可以有返回值                return i;           });           for(int i=0;i<100;i++){                System.out.println(Thread.currentThread().getName()+"循环变量i的值"+i);                if(i ==20){                     //实质以Callable对象来创建和返回线程                     new Thread(task, "返回值的线程").start();                }           }           //获取线程返回值           try {                System.out.println("子线程的返回值:"+task.get());           } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();           } catch (ExecutionException e) {                // TODO Auto-generated catch block                e.printStackTrace();           }     }}
0 0
原创粉丝点击