多线程第一种创建方式
继承Thread类
package CreatThread;
/**
* Description:创建多线程类的第一种方式, 继承Thread类
* Thread是一个类,它实现了Runable接口
* 使用方式:ThreadDemo threadDemo = new ThreadDemo();
* threadDemo.start();
* 直接创建一个对象,因为它继承了Thread类,所以它就是一个线程.直接调用start方法.
* @Author Fann
* @Data 2019/2/1
*/
public class ThreadDemo extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" ExtendsThread");
}
}
多线程第二种创建方式
实现Runnable接口
package CreatThread;
/**
* Description:创建多线程类的第二种方式 实现Runnable接口
* Runnable是一个接口,需要用implements
* 使用方式:RunnableDemo runnableDemo = new RunnableDemo();
* Thread thread = new Thread( runnableDemo );
* thread.start();
* 先创建一个类,它是Runnable类型的,需要加入到一个Thread中,然后就成为了一个线程,就可以调用线程的start方法.
* @Author Fann
* @Data 2019/2/1
*/
public class RunnableDemo implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" RunnableDemo");
}
}
多线程第三种创建方式
实现Callable接口
package CreatThread;
import java.util.concurrent.Callable;
/**
* Description:多线程类的第三种创建方式: 实现Callable接口
* 需要重写call方法.这个方法会抛出异常,会有返回值.
* 使用方式: ExecutorService exec = Executors.newSingleThreadExecutor();
* CallableDemo callableDemo = new CallableDemo();
* Future<Integer> future = exec.submit( callableDemo );
*
* @Author Fann
* @Data 2019/2/1
*/
public class CallableDemo implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println(" CallableDemo");
return 1000;
}
}
三种方式进行演示:
package CreatThread;
import java.util.concurrent.*;
/**
* Description:
*
* @Author Fann
* @Data 2019/2/1
*/
public class Main {
public static void main(String[] args) {
System.out.println("Main");
//第一种,继承Thread类
ThreadDemo threadDemo = new ThreadDemo();
threadDemo.start();
//第二种,实现Runnable接口
RunnableDemo runnableDemo = new RunnableDemo();
Thread thread = new Thread( runnableDemo );
thread.start();
//第三种,实现Callable接口
ExecutorService exec = Executors.newSingleThreadExecutor();
CallableDemo callableDemo = new CallableDemo();
Future<Integer> future = exec.submit( callableDemo );
try {
Integer integer = future.get();
future.cancel( false );
System.out.println(integer);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
PS:run和start的区别:
start() 是启动一个新线程,只可以被调用一次
run() 新线程启动之后会自动调用run方法,可以重复调用
package CreatThread;
import java.util.concurrent.*;
/**
* Description:
*
* @Author Fann
* @Data 2019/2/1
*/
public class Main {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+" MainRunning");
RunnableDemo runnableDemo = new RunnableDemo();
Thread subThread = new Thread( runnableDemo,"subThread" );
subThread.run(); //在这里调用run 是在主线程种调用run,没有达到多线程的效果
subThread.start();//调用start后是重新启动了一个新线程,它会自己调用run方法
}
}
main MainRunning
main RunnableDemo
subThread RunnableDemo
三种创建方式的区别:
三种创建方式的区别:
1.继承Thread类为单继承,不能继承其它类,而实现Runnable接口的类可以继承其他类(多实现).
所以实现Runnable接口更加灵活.
2.通过实现Runnable接口的方式可以实现多线程内的资源共享
3.实现Runnable接口线程类的多个线程,可以更方便的访问同一个遍历,而Thread类需要进行内部类替换.
4.线程池只能存放Runnable或者Callable类的线程,不能直接放入继承Thread类的线程
5.Callable规定的方法是call() 而Runnable规定的方法是run()
Callable的任务执行完毕后可以返回值,而Runnable的任务是不能返回值的.
call()方法可以抛出异常,而run()方法不行.
6.运行Callable任务可以得到一个Future对象,Future表示异步计算的结果
它提供检查计算是否完成的方法,以等到计算的完成,并检索计算的结果.
通过Future对象可了解任务的执行情况,可取消任务的执行,还可以获取任务执行的结果.
Executors是线程池的工具类
子线程的结果可以返回给主线程,并且子线程的执行可以被取消