继承Thread类
第一种方式是继承Thread类,创建Thread对象,调用start方式开始线程
代码实现如下
class Main {
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {//开启两个线程
ThreadDemo threadDemo = new ThreadDemo();
threadDemo.start();
}
System.out.println(Thread.currentThread().getName()+"运行结束");
}
static class ThreadDemo extends Thread{
@Override
public void run() {
for (int i = 0; i < 5; i++) {//循环输出5次
System.out.println(getName()+" "+i);
}
System.out.println(getName()+" 运行结束");
}
}
}
实现Runnable接口
第二种方式是实现Runnable接口,创建Thread对象,在构造方法传递实现Runnable的对象引用
代码实现如下
package com.huangkang.fourthread.create;
public class SecondThread {
public static final int MAX_TURN = 5;
public static String getCurThreadName(){
return Thread.currentThread().getName();
}
static int threadNo = 1;
public static void main(String[] args) {
//Thread thread = new Thread(new ThreadDemo());
// Thread thread = new Thread(()->{
// System.out.println("第二种");
// });
// Thread thread = new Thread(new Runnable() {
// @Override
// public void run() {
// System.out.println("第二种");
// }
// });
// thread.start();
for (int i = 0; i < 2; i++) {
Thread thread = new Thread(new ThreadDemo(),"ThreadDemo="+threadNo++);
thread.start();
}
System.out.println(getCurThreadName()+" 运行结束");
}
static class ThreadDemo implements Runnable{
@Override
public void run() {
System.out.println("第二种");
for (int i = 0; i < MAX_TURN; i++) {
System.out.println(Thread.currentThread().getName()+",轮次:"+i);
}
System.out.println(Thread.currentThread().getName()+" 运行结束");
}
}
}
实现Callable接口
第三种方式是实现Callable接口,并且结合FutureTask类,创建Thread类,在构造方法传递FutureTask的引用,前面两种创建方式都是没有返回值的,实现callable的是有返回值的,通过FutureTask的get方法可以阻塞式的获取结果。
代码实现如下
package com.huangkang.fourthread.create;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
public class ThirdThread {
public static final int MAX_TURN = 5;
public static final int COMPUTE_TIMES = 100000000;
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<Long> task = new FutureTask<>(new ThreadDemo());
Thread thread = new Thread(task, "returnableThread");//⑤
thread.start();
Thread.sleep(500);
System.out.println(Thread.currentThread().getName()+" 让子弹飞一会儿");
System.out.println(Thread.currentThread().getName()+" 做一点自己的事情");
System.out.println(Thread.currentThread().getName()+" 获取并发任务的执行结果");
try {
System.out.println(Thread.currentThread().getName()+" 线程占用时间"+ task.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 运行结束");
}
static class ThreadDemo implements Callable<Long>{
@Override
public Long call() throws Exception {
long startTime = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+" 开始运行");
Thread.sleep(1000);
for (int i = 0; i < COMPUTE_TIMES; i++) {
i = i * 10000;
}
long used = System.currentTimeMillis() - startTime;
System.out.println(Thread.currentThread().getName()+" 线程运行结束");
return used;
}
}
}
ExecutorService线程池
第四种方式是通过线程池的方式,因为每次创建销毁线程在高并发的场景下效率不高,和数据库线程池一样,使用完成把线程连接返回线程池
代码实现如下
package com.huangkang.fourthread.create;
import java.util.concurrent.*;
public class FourThread {
public static final int MAX_TURN = 5;
public static final int COMPUTE_TIMES = 100000000;
private static ExecutorService pool = Executors.newFixedThreadPool(2);
public static void main(String[] args) throws ExecutionException, InterruptedException {
pool.execute(new DemoThread());
Future<Long> submit = pool.submit(new ReturnAbleTask());
Long l = submit.get();
System.out.println(l);
}
static class DemoThread implements Runnable{
@Override
public void run() {
for (int i = 0; i < MAX_TURN; i++) {
System.out.println(Thread.currentThread().getName()+",轮次"+i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
static class ReturnAbleTask implements Callable<Long>{
@Override
public Long call() throws Exception {
long startTime = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+" 开始运行");
Thread.sleep(10);
for (int i = 0; i < MAX_TURN; i++) {
System.out.println(Thread.currentThread().getName()+",轮次"+i);
}
long used = System.currentTimeMillis() - startTime;
System.out.println(Thread.currentThread().getName()+" 线程运行结束");
return used;
}
}
}