创建线程的四种方式

1.继承于Thread类,重写run()方法;
2.实现Runable接口,实现里面的run()方法;
前两种不用多说
3.使用 FutureTask 实现有返回结果的线程,可以返回线程执行结果

public class Test {
  public static void main(String[] args) throws InterruptedException, ExecutionException {
    FutureTask task = new FutureTask(new MyCallable());
    //创建一个线程,异步计算结果
    Thread thread = new Thread(task);
    thread.start();
    //主线程继续工作
    Thread.sleep(1000);
    System.out.println("主线程等待计算结果...");
    //当需要用到异步计算的结果时,阻塞获取这个结果
    Double d = task.get();
    System.out.println("计算结果是:"+d);
    //用同一个 FutureTask 再起一个线程
    Thread thread2 = new Thread(task);
    thread2.start();
	}
}
class MyCallable implements Callable{
    @Override
    public Double call() {
         double d = 0;
         try {
             System.out.println("异步计算开始.......");
              d = Math.random()*10;
             d += 1000;
            Thread.sleep(2000);
             System.out.println("异步计算结束.......");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return d;
    }
}

4.使用ExecutorService、Executors 线程池。

public class MyTest {
    public static void main(String[] args) {
         //创建一个只有一个线程的线程池
         ExecutorService executorService = Executors.newFixedThreadPool(3);
         //创建任务,并提交任务到线程池中
         executorService.execute(new MyRunable("任务1"));
         executorService.execute(new MyRunable("任务2"));
         executorService.execute(new MyRunable("任务3"));
    }
}

class MyRunable implements Runnable{
    private String taskName;
    public MyRunable(String taskName) {
        this.taskName = taskName;
    }
    @Override
    public void run() {
        System.out.println("线程池完成任务:"+Thread.currentThread().getName()+taskName);
    }
}

二、关于run()方法的思考
看看下面这种情况:线程类Thread 接收了外部任务,同时又用匿名内部类的方式重写了内部的run()方法,这样岂不是有两个任务,那么究竟会执行那个任务呢?还是两个任务一起执行呢?

public class TestNeibu{
	public static void main(String[] args) {
		Thread thread = new Thread(new MyTask()){
	        @Override
	        public void run() {//重写Thread类的run方法
	            System.out.println("Thread 类的run方法");
	        }
	    };
	    //线程启动
	    thread.start();
	}
	
}
class MyTask implements Runnable{
    //重写run方法
    @Override
    public void run() {
        //任务内容....
        System.out.println("这是Runnable的run方法");
    }
}

运行结果如下:

Thread 类的run方法

Thread类的run方法在没有重写的情况下,是判断一下是否有Runnable 对象传进来,如果有,那么就调用Runnable 对象里的run方法;否则,就什么都不干,线程结束。所以,针对上面的例子,一旦你继承重写了Thread类的run()方法,而你又想可以接收Runable类的对象,那么就要加上super.run(),执行没有重写时的run方法,改造如下

		Thread thread = new Thread(new MyTask()){
	        @Override
	        public void run() {//重写Thread类的run方法
	           //调用父类Thread的run方法,即没有重写时的run方法
	            super.run();
	            System.out.println("Thread 类的run方法");
	        }
	    };
	    thread.start();

你可能感兴趣的:(多线程)