1.启动线程的方式
- 子类继承Thread,重写run()方法
* class PrimeThread extends Thread {
* long minPrime;
* PrimeThread(long minPrime) {
* this.minPrime = minPrime;
* }
* public void run() {
* // compute primes larger than minPrime
* . . .
* }
* }
* PrimeThread p = new PrimeThread(143);
* p.start();
- 类实现Runnable接口,重写run方法,作为参数传入Thread
* class PrimeRun implements Runnable {
* long minPrime;
* PrimeRun(long minPrime) {
* this.minPrime = minPrime;
* }
*
* public void run() {
* // compute primes larger than minPrime
* . . .
* }
* }
* PrimeRun p = new PrimeRun(143);
* new Thread(p).start();
2.实现接口
public
class Thread implements Runnable {
...
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
...
@Override
public void run() {
if (target != null) {
target.run();//执行我们重写run()方法中的逻辑
}
}
}
该类已经实现了Runnable 接口,重写了run方法
再看看Runnable 接口
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
再看看@FunctionalInterface注解
/**
* An informative annotation type used to indicate that an interface
* type declaration is intended to be a <i>functional interface</i> as
* defined by the Java Language Specification.
* Conceptually, a functional interface has exactly one abstract
* method.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
该注解作用是规范功能接口定义,一个功能接口只有一个抽象方法
3.变量
private volatile String name; //volatile 类型的name
private int priority; //优先级
private Thread threadQ; //不晓得
private long eetop; //JVM中的JavaThread指针
/* Whether or not to single_step this thread. */
private boolean single_step; //是否单步执行
/* Whether or not the thread is a daemon thread. */
private boolean daemon = false; //是否守护进程
/* JVM state */
private boolean stillborn = false; //是否存活
/* What will be run. */
private Runnable target; //新thread将执行的内容
/* The group of this thread */
private ThreadGroup group; //线程组
/* The context ClassLoader for this thread */
private ClassLoader contextClassLoader; //thread的类加载器
/* The inherited AccessControlContext of this thread */
private AccessControlContext inheritedAccessControlContext;//线程继承的访问控制上下文
/* For autonumbering anonymous threads. */
private static int threadInitNumber; //计数变量,用在nextThreadNum方法中为匿名线程生成名称
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null; //与线程局部变量相关
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; //与线程局部变量相关
/*
* The requested stack size for this thread, or 0 if the creator did
* not specify a stack size. It is up to the VM to do whatever it
* likes with this number; some VMs will ignore it.
*/
private long stackSize; //此线程请求的堆栈大小,如果创建者未指定堆栈大小,则为0
/*
* JVM-private state that persists after native thread termination.
*/
private long nativeParkEventPointer;
/*
* Thread ID
*/
private long tid; //线程ID
/* For generating thread ID */
private static long threadSeqNumber; //计数变量,用在nextThreadID方法中为线程生成ID
/* Java thread status for tools,
* initialized to indicate thread 'not yet started'
*/
private volatile int threadStatus = 0; //线程状态
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
/**
* The argument supplied to the current call to
* java.util.concurrent.locks.LockSupport.park.
* Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
* Accessed using java.util.concurrent.locks.LockSupport.getBlocker
*/
volatile Object parkBlocker; //用于LockSupport.park(Object)方法中,用于引用该方法参数
/* The object in which this thread is blocked in an interruptible I/O
* operation, if any. The blocker's interrupt method should be invoked
* after setting this thread's interrupt status.
*/
private volatile Interruptible blocker; //线程在执行可中断IO操作时阻塞该线程的对象,线程的中断状态被设置后blocker的interrupt方法会被调用
private final Object blockerLock = new Object(); // 设置上述blocker变量时用的锁
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;//默认优先级
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
守护线程需要解释一下:
用户线程:我们平常创建的普通线程。
守护线程:用来服务于用户线程;不需要上层逻辑介入。
当线程只剩下守护线程的时候,JVM就会退出;补充一点如果还有其他的任意一个用户线程还在,JVM就不会退出。
thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
在Daemon线程中产生的新线程也是Daemon的。
守护线程不能用于去访问固有资源,比如读写操作或者计算逻辑。因为它会在任何时候甚至在一个操作的中间发生中断。
Java自带的多线程框架,比如ExecutorService,会将守护线程转换为用户线程,所以如果要使用后台线程就不能用Java的线程池。
当主线程结束时,结束其余的子线程(守护线程)自动关闭,就免去了还要继续关闭子线程的麻烦。如:Java垃圾回收线程就是一个典型的守护线程;内存资源或者线程的管理,但是非守护线程也可以。
4.线程状态枚举类
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW, //创建
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE, //运行
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED, //阻塞
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING, //等待
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING, //指定时间等待
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED; //终止
}
引用一张非常好的图片
5.构造方法
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0);
}
public Thread(String name) {
init(null, null, name, 0);
}
public Thread(ThreadGroup group, String name) {
init(group, null, name, 0);
}
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name) {
init(group, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
init(group, target, name, stackSize);
}
可以看出调用的都是init方法
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();//将执行该线程的线程作为父线程,eg:main线程
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();//从security 取线程组
}
/* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup(); //如果security 没有就从父线程中取线程组
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();//调用security.checkAccess(this)方法
/*
* Do we have the required permissions?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);//检查权限
}
}
g.addUnstarted();
//g 为当前线程所属的线程组。意为添加未开始的线程 ,对于没有调用 start 方法的线程,其所属的线程组只是把 UnstartedThreads 值加一,并没有真正的添加,真正将线程添加进线程组的方法是ThreadGroup.add。
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;//赋值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();//设置tid
}
6.sleep
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++; //仅仅是将millis+1
}
sleep(millis);
}
第二个方法没有准确实现线程的纳秒级等待,直接millis++
7.start
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) //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); //将要启动的线程添加到线程组中,此时未启动的线程数量-1
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 */
}
}
}
private native void start0();
8 .exit
/**
* This method is called by the system to give a Thread
* a chance to clean up before it actually exits.
*/
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
从注释中可以看出该方法是为了在线程退出之前释放资源
9.stop
@Deprecated
public final void stop() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
checkAccess();
if (this != Thread.currentThread()) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// A zero status value corresponds to "NEW", it can't change to
// not-NEW because we hold the lock.
if (threadStatus != 0) {
resume(); // Wake up thread if it was suspended; no-op otherwise
}
// The VM can handle all thread states
stop0(new ThreadDeath());
}
10.interrupt
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);
1) this.interrupted(): 判断线程终止的状态, 执行后具有将状态标志置为false的功能
2) this.isInterrupted():判断线程终止的状态,不具有清除状态标志的功能
还有一些方法,这里不再多叙…
参考资料:
https://blog.csdn.net/u011676300/article/details/79072362
https://blog.csdn.net/qq_32726809/article/details/82704434
https://www.jianshu.com/p/9aa8c0f82ffc
https://www.cnblogs.com/liukaifeng/p/10052601.html
https://zhuanlan.zhihu.com/p/28049750
https://blog.csdn.net/pengqiaowolf/article/details/80442071
https://www.sohu.com/a/237335260_659256