Thread 初探
前言:
此博文创建线程池代码仅供学习Executors类所使用,实际业务中不推荐这种创建线程池方式.有可能会触发OOM异常.
创建一个线程: 实现Runnable
/**
* 实现RunnableDemo
*/
public class RunnableDemo {
public static void main(String[] args) {
Thread thread = new Thread(new TestDemo2());
thread.start();
}
}
class TestDemo2 implements Runnable {
//重写run方法
@Override
public void run() {
System.out.println("线程调用了...");
}
}
创建一个线程: 继承Thread
/**
* 继承Thread实现线程
*/
public class ThreadDemo {
public static void main(String[] args) {
Thread thread = new Thread(new TestDemo3());
thread.start();
}
}
class TestDemo3 extends Thread {
//重写父类run方法
@Override
public void run() {
System.out.println("线程调用了....");
super.run();
}
}
创建一个线程: 实现Callable
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* 携带返回值的线程实现
*/
public class CallableDemo {
public static void main(String[] args) {
//创建一个用于接受callable的值FutureTask对象
FutureTask ft = new FutureTask(new TestDemo());
//启动线程
new Thread(ft).start();
try {
//打印结果.
System.out.println(ft.get());
} catch (Exception e) {
System.out.println("读取返回值出错了...");
}
}
}
//实现一个callable线程
class TestDemo implements Callable {
@Override
public Object call() throws Exception {
//申明一个变量,用于接受循环体计算结果
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += (int) (Math.random() * 10);
}
return sum;
}
}
创建一个线程: 通过匿名内部类来实现线程
/**
* 通过匿名内部类来实现线程
*/
public class AnonymousInnerThreadDemo {
public static void main(String[] args) {
//JDK1.8 Lambda表达式实现 -> 匿名内部类方式
Runnable runnable = () -> System.out.println("runnable线程调用了...");
Thread thread = new Thread(runnable);
thread.start();
}
}
线程池相关
import java.util.concurrent.*;
/**
* 创建一个线程池
*/
public class ThreadPoolDemo {
public static void main(String[] args) throws Exception {
//创建一个单线程池 - 任务量较大的情况下容易造成OOM异常
//主要因为任务队列增长无限制.
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
singleThreadPool.submit(() -> {
System.out.println("线程执行了..." + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
singleThreadPool.shutdown();
//创建一个固定大小的线程池
//此线程池若全在使用中,有可能触发OOM异常
//主因:任务队列增长无限制.
ExecutorService doubleThreadPool = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
doubleThreadPool.execute(() -> {
System.out.println("线程池启动..并执行任务..." + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
doubleThreadPool.shutdown();
//创建一个可缓存的线程池
//此线程池不建议使用,容易造成OOM
//主因:它只会重新使用空闲的线程,若每一个业务需要一定时间执行,容易内存溢出.
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10000000; i++) {
cachedThreadPool.execute(()->{
System.out.println("缓存线程池启动..并执行任务..." + Thread.currentThread().getName()
);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
cachedThreadPool.shutdown();
//创建一个线程池(可指定执行时间)
//这个可以在业务中使用. 一般用于系统任务.
ScheduledExecutorService sesPool = Executors.newScheduledThreadPool(5);
//一般用于任务调度.(任务,启动后延迟多少时间执行,间隔多少时间执行一次,时间单位:毫秒)
sesPool.scheduleAtFixedRate(() -> System.out.println("任务调度执行了...." + Thread.currentThread().getName()),
1000, 5, TimeUnit.MILLISECONDS);
//关闭线程池 -
sesPool.shutdown();
}
}