1、继承Thread类创建线程
1 package concurrent; 2 3 /** 4 * @author zsh 5 * @site qqzsh.top 6 * @company wlgzs 7 * @create 2019-05-01 15:05 8 * @Description 创建线程的三种方式 9 * 1、继承Thread类创建线程 10 * (1) 定义Thread的子类,并重写该类的run方法,该run方法的方法体就代表了线程 11 * 要完成的任务。因此把run()方法称为执行体。 12 * (2) 创建Thread子类的实例,即创建了该线程对象。 13 * (3) 调用线程对象的start()方法来启动该线程。 14 */ 15 public class FirstThreadTest extends Thread { 16 int i = 0; 17 18 @Override 19 public void run() { 20 for (; i < 100; i++) { 21 System.out.println(getName()+" "+i); 22 } 23 } 24 25 public static void main(String[] args) { 26 for (int i = 0; i < 100; i++) { 27 System.out.println(Thread.currentThread().getName()+":"+i); 28 if (i == 20){ 29 new FirstThreadTest().start(); 30 new FirstThreadTest().start(); 31 } 32 } 33 } 34 }
2、实现Runnable接口创建线程类
1 package concurrent; 2 3 /** 4 * @author zsh 5 * @site www.qqzsh.top 6 * @company wlgzs 7 * @create 2019-05-04 9:59 8 * @description 创建线程的三种方式 9 * 2、实现Runnable接口创建线程类 10 * (1) 定义runnable接口的实现类,并重写该接口的run方法,该run方法的方法体同样 11 * 是该线程的执行体。 12 * (2) 创建Runnable实现类的实例,并依次实例作为Thread得到target来创建Thread对象, 13 * 该Thread对象才是真正的线程对象。 14 * (3) 调用线程对象的start()方法来启动线程。 15 */ 16 public class RunnableThreadTest implements Runnable{ 17 private int i; 18 19 @Override 20 public void run() { 21 for (i = 0; i < 100; i++) { 22 System.out.println(Thread.currentThread().getName()+" "+i); 23 } 24 } 25 26 public static void main(String[] args) { 27 for (int i = 0; i < 100; i++) { 28 System.out.println(Thread.currentThread().getName()+":"+i); 29 if (i == 20){ 30 RunnableThreadTest rtt = new RunnableThreadTest(); 31 new Thread(rtt,"新线程1").start(); 32 new Thread(rtt,"新线程2").start(); 33 } 34 } 35 } 36 }
3、通过Callable和Future创建线程
1 package concurrent; 2 3 import java.util.concurrent.Callable; 4 import java.util.concurrent.ExecutionException; 5 import java.util.concurrent.FutureTask; 6 7 /** 8 * @author zsh 9 * @site www.qqzsh.top 10 * @company wlgzs 11 * @create 2019-05-04 10:35 12 * @description 创建线程的三种方式 13 * 3、通过Callable和Future创建线程 14 * (1) 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体, 15 * 并且有返回值。 16 * (2) 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask 17 * 对象封装了该Callable对象的call()方法的返回值。 18 * (3) 使用FutureTask对象作为Thread对象的target创建并启动新线程。 19 * (4) 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。 20 */ 21 public class CallableThreadTest implements Callable<Integer> { 22 23 @Override 24 public Integer call() throws Exception { 25 int i = 0; 26 for (;i<100;i++){ 27 System.out.println(Thread.currentThread().getName()+" "+i); 28 } 29 return i; 30 } 31 32 public static void main(String[] args) { 33 CallableThreadTest ctt = new CallableThreadTest(); 34 FutureTask<Integer> ft = new FutureTask<>(ctt); 35 for (int i = 0; i < 100; i++) { 36 System.out.println(Thread.currentThread().getName()+" 的循环变量i的值为;"+i); 37 if (i == 20){ 38 new Thread(ft,"有返回的线程").start(); 39 } 40 } 41 try { 42 System.out.println("子线程的返回值为"+ft.get()); 43 } catch (InterruptedException e) { 44 e.printStackTrace(); 45 } catch (ExecutionException e) { 46 e.printStackTrace(); 47 } 48 } 49 }