bilibili-Java并发学习笔记1 Thread 类
基于 java 1.8.0
P5_从Thread与Runnable说开去
- Thread 概览
java.lang.Thread
public
class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
private volatile String name;
private int priority;
private Thread threadQ;
private long eetop;
/* 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;
/* The group of this thread */
private ThreadGroup group;
/* The context ClassLoader for this thread */
private ClassLoader contextClassLoader;
/* The inherited AccessControlContext of this thread */
private AccessControlContext inheritedAccessControlContext;
/* For autonumbering anonymous threads. */
private static int threadInitNumber;
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;
/*
* JVM-private state that persists after native thread termination.
*/
private long nativeParkEventPointer;
/*
* Thread ID
*/
private long tid;
/* For generating thread ID */
private static long threadSeqNumber;
/* 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;
/* 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;
private final Object blockerLock = new Object();
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
}
线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
每个线程都有一个优先级
,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序
。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级
,并且当且仅当创建线程是守护线程时,新线程才是守护程序
。
当 Java 虚拟机启动时,通常都会有单个非守护线程
(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:
- 调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。
- 非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。
- 线程优先级
private int priority;
/**
* 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;
最小值为 1,最大值为 10,缺省值为 5,值越大,优先级越高;
Thread thread1 = new Thread();
thread1.setPriority(6);
- 守护线程
当且仅当创建线程是守护线程时,新线程才是守护程序;启动后不能再进行设置守护线程:
Thread thread1 = new Thread();
thread1.setPriority(6);
thread1.start();
thread1.setDaemon(true);
// Exception in thread "main" java.lang.IllegalThreadStateException
// at java.lang.Thread.setDaemon(Thread.java:1359)
// at new_package.thread.p5.MyTest.main(MyTest.java:18)
守护线程又称后台线程,gc 线程其实就是一个守护线程,当只有守护线程存在,非守护线程全部停止时,jvm 会退出运行;
- 标识名
可以指定,否则使用缺省名称;
// 构造函数指定线程名称
Thread thread1 = new Thread("Thread-no39102");
// 方法设置名称
thread1.setName("Thread-no39102");
缺省名称
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
// "Thread-" + nextThreadNum()
/* For autonumbering anonymous threads. */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
- ThreadGroup
ThreadGroup threadGroup = new ThreadGroup("my-threadgroup-name");
Thread thread2 = new Thread(threadGroup,"my-thread-name");
- Runnable
/*
* @author Arthur van Hoff
* @see java.lang.Thread
* @see java.util.concurrent.Callable
* @since JDK1.0
*/
@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();
}