实现并启动线程有两种方法
1、写一个类继承自Thread类,重写run()方法,用start()方法启动线程。
2、写一个类实现Runnable接口,实现run()方法,用new Thread(Runnable target).start()方法。
多线程原理
start()排队,CPU选中后执行就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()。
代码例子如下
// 1.1使用匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
}).start();
// 1.2使用 lambda expression
new Thread(() -> System.out.println("Hello world !")).start();
// 2.1使用匿名内部类
Runnable race1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
};
// 2.2使用 lambda expression
Runnable race2 = () -> System.out.println("Hello world !");
race1.run();
race2.run();
另外,Java 线程池 ThreadPoolExecutor 也是不错的多线程设计必用的,那如何设计一个比较好的线程池API让别的方法调用?下面是一个例子,可以作为util来用
package cn.com.test.enums;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 功能描述:线程池枚举类
*/
@Slf4j
public enum ExecutorEnum {
DELIVER_POOL("testthreadpool",
new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2,
Runtime.getRuntime().availableProcessors() * 3,
1,
TimeUnit.MINUTES,
new ArrayBlockingQueue<>(100),
new NamedThreadFactory("testfac")));
private final String name;
private final ThreadPoolExecutor executor;
ExecutorEnum(String name, ThreadPoolExecutor executor) {
this.executor = executor;
this.name = name;
}
public String getName() {
return name;
}
private static class NamedThreadFactory implements ThreadFactory {
private final AtomicInteger sequence = new AtomicInteger(1);
private final String prefix;
public NamedThreadFactory(String prefix) {
this.prefix = prefix;
}
@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
int seq = sequence.getAndIncrement();
thread.setName(prefix + (seq > 1 ? "-" + seq : ""));
if (!thread.isDaemon()) {
thread.setDaemon(true);
}
return thread;
}
}
private static final String REQUEST_ID="requestId";
public void submit(Runnable task) {
String requestId = this.getRequestId();
executor.submit(() -> {
try {
MDC.put(REQUEST_ID, requestId);
task.run();
} catch (Exception e) {
log.error("task.run err", e);
} finally {
MDC.remove(REQUEST_ID);
}
});
}
public <T> Future<T> submit(Callable<T> task) {
String requestId = this.getRequestId();
Callable<T> callable = () -> {
T call = null;
try {
MDC.put(REQUEST_ID, requestId);
call = task.call();
} catch (Exception e) {
log.error("task.call err", e);
} finally {
MDC.remove(REQUEST_ID);
}
return call;
};
return executor.submit(callable);
}
private String getRequestId(){
String requestId = MDC.get(REQUEST_ID);
if (StringUtils.isEmpty(requestId)) {
requestId = UUID.randomUUID().toString().replace("-", "");
}
return requestId;
}
}
//使用例子
ExecutorEnum.DELIVER_POOL.submit( () -> {mymethod();});