一、继承Thread
package com.caiweiwei.lianxi.controller; import java.util.Random; public class ThreadTest { public static void main(String[] args) { Runable lufei=new Runable(); lufei.setName("路飞");//设置线程名称 Runable caimou=new Runable(); caimou.setName("蔡某"); Runable shashibiye=new Runable(); shashibiye.setName("莎士比亚"); //线程启动 lufei.start(); caimou.start(); shashibiye.start(); } } class Runable extends Thread{ //实现run方法 @Override public void run() { Integer speed= new Random().nextInt(100); for (int i = 0; i <=100 ; i++) { try { Thread.sleep(1000);//当前线程休眠一秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.getName()+"已前进"+(i*speed)+"米"); } } }
二、实现Runnable接口
package com.caiweiwei.lianxi.controller; import java.util.Random; public class ThreadTest2 { public static void main(String[] args) { Runner2 liuxiang = new Runner2(); Thread thread1 = new Thread(liuxiang); thread1.setName("路飞"); Thread laoqi = new Thread(new Runner2()); laoqi.setName("蔡某"); Thread op = new Thread(new Runner2()); op.setName("莎士比亚"); thread1.start(); laoqi.start(); op.start(); } } class Runner2 implements Runnable{ @Override public void run() { Integer speed=new Random().nextInt(100); for (int i = 0; i <100 ; i++) { try { Thread.sleep(1000);//当前线程休眠1秒 } catch (InterruptedException e) { e.printStackTrace(); } //Thread.currentThread()用于获取当前执行的线程对象 //在Runnable中是无法使用this获取到当前线程对象的 System.out.println(Thread.currentThread().getName() + "已前进" + (i * speed) + "米(" + speed + "米/秒)"); } } }
三、实现Callable接口
package com.caiweiwei.lianxi.controller; import java.util.Random; import java.util.concurrent.*; public class ThreadTest3 { public static void main(String[] args) throws ExecutionException, InterruptedException { //创建一个线程池。里面天生有3个“空”线程。Executors是调度器,对线程池进行管理 ExecutorService executorService= Executors.newFixedThreadPool(3); Runner3 c=new Runner3();//实例化callable对象 c.setName("莎士比亚"); Runner3 a=new Runner3(); a.setName("蔡某"); Runner3 b=new Runner3(); b.setName("路飞"); //将这个对象扔到线程池中,线程池自动分配一个线程来运行liuxiang这个对象的call方法 //Future用于接受线程内部call方法的返回值 Future<Integer> result1=executorService.submit(a); Future<Integer> result2=executorService.submit(b); Future<Integer> result3=executorService.submit(c); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } executorService.shutdown();//关闭线程池释放所有资源 System.out.println("刘翔累计跑了" + result1.get() + "米" ); System.out.println("老齐累计跑了" + result2.get() + "米" ); System.out.println("路飞累计跑了" + result3.get() + "米" ); } } class Runner3 implements Callable { private String name; public void setName(String name) { this.name = name; } //实现Callable接口可以允许我们的线程返回值或抛出异常 @Override public Object call() throws Exception { Integer speed=new Random().nextInt(100); Integer distince=0;//总共奔跑的距离 for (int i = 0; i <100 ; i++) { Thread.sleep(10); distince=distince+i*speed; System.out.println(this.name + "已前进" + distince + "米(" + speed + "米/秒)"); } return distince; } }
创建线程的三种方式对比
image.png
并发工具包-Concurrent
JDK1.5以后为我们专门提供了一个并发工具包java.util.concurrent。u java.util.concurrent 包含许多线程安全、测试良好、高性能的并发构建块。创建 concurrent 的目的就是要实现 Collection 框架对数据结构所执行的并发操作。通过提供一组可靠的、高性能并发构建块,开发人员可以提高并发类的线程安全、可伸缩性、性能、可读性和可靠性。