1.创建线程
- 继承Thread类
- 实现Runnable接口或者Callable接口
- 通过线程池
public static void main(String[] args) {
//创建线程1
new Thread(
() -> System.out.println(Thread.currentThread().getName())
).start();
//创建线程2
new Thread(new MyThread()).start();
//创建线程3
ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1, 0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
singleThreadPool.execute(
() -> System.out.println(Thread.currentThread().getName())
);
singleThreadPool.shutdown();
}
static class MyThread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
2.源码分析
1.创建线程
new Thread(
() -> System.out.println(Thread.currentThread().getName())
).start();
new Thread进入构造函数:
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
这里调用nextThreadNum方法生成一个自增id,再加上Thread作为线程名字
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
之后调用init方法:
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}
接着调用6个参数的init方法:
主要的操作有:
设置线程名称,设置线程组(父线程默认是当前线程,默认线程所属组为父线程组),获取优先级和是否是后台进程,最后保存传入的Runnable的run方法到target
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */
/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}
/* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
/*
* Do we have the required permissions?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
acc != null ? acc : AccessController.getContext();
this.target = target;
setPriority(priority);
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
2.启动线程
首先判断线程状态,然后将其放入线程组,最后调用start0(native方法)启动线程,如果启动失败从线程组中移除
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
启动完成后,会调用run方法:
@Override
public void run() {
if (target != null) {
target.run();
}
}