多线程
线程创建方式总结:
方式一:继承Thread
public class ThreadDemo1 { public static void main(String[] args) { MyThread1 myThread1 = new MyThread1(); myThread1.start(); MyThread1 myThread2 = new MyThread1(); myThread2.start(); MyThread1 myThread3 = new MyThread1(); myThread3.start(); } } class MyThread1 extends Thread{ public void run() { System.out.println("666"); } }1.编写线程类,线程类继承Thread,在该类中编写run方法
2.在main方法中创建线程类对象,并调用该对象的start方法 开启线程
方式二:实现Runnable接口
public class ThreadDemo2 { public static void main(String[] args) { MyThread2 myThread2 = new MyThread2(); Thread t1 = new Thread(myThread2); t1.start(); Thread t2 =new Thread(myThread2); t2.start(); } } class MyThread2 implements Runnable{ @Override public void run() { System.out.println("555"); } }
1.创建线程类实现runnable接口,重写run方法
2. 在main方法中创建线程类的实例,通过该线程类的实例,创建线程对象,调用start方法 开启线程
方式三:实现Callable接口
public class ThreadDemo3 { public static void main(String[] args) throws InterruptedException, ExecutionException { MyThread3 mt = new MyThread3(); FutureTask<Integer> task = new FutureTask<Integer>(mt); Thread t= new Thread(task); t.start(); Integer result = task.get(); //获取call()的返回值 System.out.println(result); } } class MyThread3 implements Callable<Integer>{ //类似于run @Override public Integer call() throws Exception { // TODO Auto-generated method stub System.out.println("333"); int a = 1; return a; } }1.创建线程类,实现Callable接口,传入线程执行结果的返回值类型泛型,重写call方法在该方法中编写线程任务
2.在main方法中,创建线程类实例,通过线程类实例创建futureTask对象,通过该对象创建出线程对象。
三种创建方式有何不同:
继承Thread:
优点:简单
缺点:
如果有多任务的话,每一个任务都要创建一个独立线程
以及继承Thread父类,无法继承其他父类
run方法无法抛出异常
实现runnable接口:
缺点:
复杂
run方法无法抛出异常
优点:可以实现其他接口继承其他类,方便多个线程共享同一个目标对象。
实现Collable接口:
优点:
call方法可以抛出异常
FutureTask对象提供了诸多操作线程任务的方法,可以通过该对象了解任务执行情况
run()和start()有什么区别:
run:
由JVM创建线程后回调的方法,不可以手动调用,如果手动调用,只是单纯执行run()方法中的内容,而不会启动线程,
start:
开启线程,开启后没有立即执行,需要过去CPU时间片后才能执行