- A+
方式一:继承Thread类
1.自定义类MyThread继承Thread类。
2.MyThread类里面重写run()方法。
3.创建线程对象。
4.启动线程。
注意:
1、启动线程使用的是start()方法而不是run()方法
2、线程不能多次启动,只能执行一次
public class ThreadTEST { public static void main(String[] args) { Thread.currentThread().setName("main thread"); MyThread myThread1 = new MyThread(); MyThread myThread2 = new MyThread(); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "前面" + i); } myThread1.setName("sub Thread A:"); myThread2.setName("sub Thread B:"); myThread1.start(); myThread2.start(); for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "后面" + i); } }} class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + i); } }}
方式二:实现Runnable接口
1.自定义类MyRunnable实现Runnable接口
2.重写run()方法
3.创建MyRunnable类的对象
4.创建Thread类的对象,并把步骤3创建的对象作为构造参数传递
5.启动线程
public class RunnableTest { public static void main(String[] args) { //设置线程名字 Thread.currentThread().setName("main thread:"); Thread thread = new Thread(new MyRunnable()); thread.setName("子线程:"); //开启线程 thread.start(); for(int i = 0; i <5;i++){ System.out.println(Thread.currentThread().getName() + i); } }} class MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + i); } }}
方式三:使用Callable和Future创建线程
和Runnable接口不一样,Callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。
import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;//实现Callable接口public class CallableTest { public static void main(String[] args) { //执行Callable 方式,需要FutureTask 实现实现,用于接收运算结果 FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyCallable()); new Thread(futureTask).start(); //接收线程运算后的结果 try { Integer sum = futureTask.get(); System.out.println(sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }} class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; }
Runnable和Callable的区别是:
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
方法四: 线程池创建线程
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;//线程池实现public class ThreadPoolExecutorTest { public static void main(String[] args) { //创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(10); ThreadPool threadPool = new ThreadPool(); for(int i =0;i<5;i++){ //为线程池分配任务 executorService.submit(threadPool); } //关闭线程池 executorService.shutdown(); }} class ThreadPool implements Runnable { @Override public void run() { for(int i = 0 ;i<10;i++){ System.out.println(Thread.currentThread().getName() + ":" + i); } } }
这个类的构造方法有六个参数:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler)
分别为:
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略