创建线程的四种方法:
继承Thread类、实现runnable接口、实现Callable接口、线程池创建线程
1.继承Thread类
public class ThreadDemo extends Thread { @Override public void run() { System.out.println("MyThread...run..."); } public static void main(String[] args) { // 创建MyThread对象 ThreadDemo t1 = new ThreadDemo() ; ThreadDemo t2 = new ThreadDemo() ; // 调用start方法启动线程 t1.start(); t2.start(); } }
2.实现Runnable接口(无返回值)
public class RunnableDemo implements Runnable{ @Override public void run() { System.out.println("MyRunnable...run..."); } public static void main(String[] args) { // 创建MyRunnable对象 RunnableDemo mr = new RunnableDemo() ; // 创建Thread对象 Thread t1 = new Thread(mr) ; Thread t2 = new Thread(mr) ; // 调用start方法启动线程 t1.start(); t2.start(); } }
3.实现Callable接口(有返回值)
public class CallableDemo implements Callable { @Override public String call() throws Exception { System.out.println("MyCallable...call..."); return "OK"; } public static void main(String[] args) throws ExecutionException, InterruptedException { // 创建MyCallable对象 CallableDemo mc = new CallableDemo() ; // 创建F FutureTask<String> ft = new FutureTask<String>(mc) ; // 创建Thread对象 Thread t1 = new Thread(ft) ; Thread t2 = new Thread(ft) ; // 调用start方法启动线程 t1.start(); // 调用ft的get方法获取执行结果 String result = ft.get(); // 输出 System.out.println(result); } }
4.线程池创建线程
public class ExecutorsDemo implements Runnable{ @Override public void run() { System.out.println("MyRunnable...run..."); } public static void main(String[] args) { // 创建线程池对象 ExecutorService threadPool =Executors.newFixedThreadPool(3); threadPool.submit(new ExecutorsDemo()) ; // 关闭线程池 threadPool.shutdown(); } }
Runnable与callable的区别:
1.runnable接口run()有返回值,callable接口call方法没有返回值,是个泛型,和Future,FutureTask配合,可以用来获取异步执行的结果。
2.callable接口的返回结果,需要调用FutureTask.get()得到,此方法会阻塞进程的继续往下执行,如果不调用不会阻塞。
3.Callable接口的call()方法允许抛出异常,而runnable的run方法,异常只能内部消化,不能继续上抛
线程run()与start()有什么区别:
start():的启动一个线程,该线程通过调用run方法,执行run方法中定义的逻辑代码,start只能调用一次,而run方法可以调用多次。
run():封装了要被线程执行的代码,可以被调用多次。