java学习——线程

第一种:extend Threadjava

第二种:implement Runnable多线程

第三种:Executors.newFixedThreadPool(int n).execute(...)测试

第一种(继承)、第二种(实现接口)是所有版本jdk一直支持,第三种(线程池)jdk1.5才开始出现。this


/*第一种
1.自定义类继承Thread
2.自定义类复写run方法
3.实例化自定义类,调用start方法(做用是启动线程并调用复写的run方法)
*/

class Demo extend Thread{
    public void run(){...}
}
class T{
    public static void main(String[] args){
        new Demo().start();   //线程1
        new Demo().start();   //线程2
        new Demo().start();   //线程3
    }
}
/*第二种【经常使用】
1.自定义类实现Runnable接口
2.自定义类复写run方法
3.实例化自定义类,把自定义类的实例做为参数实例化Thread类(可实例化多个,就是所谓的多线程),而后调用start方法
*/

class Demo implement Runnable{
    public void run(){...}
}
class T{
    public static void main(String[] args){
        Demo demo = new Demo();
        new Thead(demo).start();   //线程1
        new Thead(demo).start();   //线程2
        new Thead(demo).start();   //线程3
    }
}

第一种和第二种方法其实同样,主要是由于java的单继承机制才出现了第二种【经常使用】方法。线程

//第三种
//简易版
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test{
    public static void main(String[] args){
        ExecutorService pool = Executors.newFixedThreadPool(3);   //建立线程池,容量为3
                for(int i=0;i<10;i++)
                {
                    pool.execute(new Runnable(){public void run(){ System.out.println();}});
                }
                Executors.newCachedThreadPool().execute(new Runnable(){public void run(){}});
                Executors.newSingleThreadExecutor().execute(new Runnable(){public void run(){}});
    }
}

//详细版(可运行进行测试)
import java.util.concurrent.*;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;

public class Test {
	public static void main(String[] args) throws ExecutionException,
	    InterruptedException {
	   System.out.println("----程序开始运行----");
	   Date date1 = new Date();

	   int taskSize = 5;
	   // 建立一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
	   ExecutorService pool = Executors.newFixedThreadPool(taskSize);
	   // 用于存听任务返回值
	   List<Future> list = new ArrayList<Future>();
	   for (int i = 0; i < taskSize; i++) {
	    Callable c = new MyCallable(i + " ");
	    // 执行任务并获取Future对象
	    //pool提交一个返回值的任务用于执行,返回一个表示任务的未决结果的Future。
	    Future f = pool.submit(c);
	    // System.out.println(">>>" + f.get().toString());
	    list.add(f);
	   }
	   // 关闭线程池
	   pool.shutdown();

	   // 遍历全部线程的返回值
	   for (Future f : list) {
	    System.out.println(">>>" + f.get().toString());
	   }

	   Date date2 = new Date();
	   System.out.println("----程序结束运行----,程序运行时间【"
	     + (date2.getTime() - date1.getTime()) + "毫秒】");
	}
}

//有返回值实现Callable,无返回值实现Runnable
class MyCallable implements Callable<Object> {
	private String taskNum;

	MyCallable(String taskNum) {
	   this.taskNum = taskNum;
	}
	//实现Callable必须实现call方法
	//计算结果,若是没法计算结果,则抛出一个异常。
	public Object call() throws Exception {
	   System.out.println(">>>" + taskNum + "任务启动");
	   Date dateTmp1 = new Date();
	   Thread.sleep(1000);
	   Date dateTmp2 = new Date();
	   long time = dateTmp2.getTime() - dateTmp1.getTime();
	   System.out.println(">>>" + taskNum + "任务终止");
	   return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
	}
}

    个人理解:code

    由Executors.newFixedThreadPool(int n)定义一个能够执行必定数量线程的线程池,pool.submit(c)把须要执行的任务扔进(提交到)线程池进行执行,这样就能够不阻塞得同时执行多个任务(即所谓的多线程)。对象

    Callable和Runnable同样是接口,二者的区别是Callable执行完call()后返回一个Object,Runnable执行完run()后不返回。call()和run()功能相同(除了有无返回值的区别)。继承

    Future是一个类型(也就是类啦),用来装Callable执行完call()后返回的Object(其实这里返回的是Object,为啥不能用Object来装,非要用Future来装呢?我也不明白,可是API说须要用这个装就用呗)。接口

    因为是多线程,每一个线程都执行完都有返回,因此须要用一个容器(即集合)——ArrayList<Future>来装。队列

    线程池的方法能够获取任务执行的返回值(这些返回值可能有用),另外,此方法也能够执行submit(T<? implement Runnable>)无返回值的方法。

    so,我以为第三种通吃,直接用第三种方式得了。

相关文章
相关标签/搜索