1.UnSafe类
UnSafe类:用于执行低级别、不安全操作的方法集合,其通过直接操作内存来保证线程安全。Unsafe和ByteBuff都能用于是获取非堆内存,但UnSafe保证了对非堆内存的操作是线程安全的,而ByteBuff不能保证。
并且其可以不用调用类的构造函数从而直接反序列化对象等。
2.Thread类
关键Field: ThreadGroup g 、Runnable target、线程名 name、初始线程栈大小stackSize、AccessControlContext acc权限控制对象
最好的调用方式:
指定运行的target对象和线程名(用于jvm进行标识)
ThreadGroup使用默认的ThreadGroup
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
- ThreadGroup主要用于管理线程(已经启动的线程,启动线程数、未启动线程数等),通常使用默认值为与主线程属于同一个组。
默认值:main,其父group为system。几个重要属性:int nUnstartedThreads = 0; int nthreads; Thread threads[];
SecurityManager security = System.getSecurityManager();
security.getThreadGroup();
************等价于****************
Thread.currentThread().getThreadGroup()
- daemon 是否是守护进程默认是false。如果是非守护进程,JVM进程必须等待所有的非守护进程完成后才能结束。如果是守护进程,那么当没有非守护进程存在的时候,JVM会直接退出,不管非守护进程是否完成。因此守护进程一般用于后台进程,可以随时中断,如分布式系统中的心跳检测线程等。
- tid 线程号,JVM进程中用于唯一的标识一个线程。
- Thread start方法,其维护ThreadGroup中的信息外,最重要的是start0()方法,其调用本地操作系统的函数。为多线程的实现提供本地操作系统的支持。同理interrupt和interrupt0方法。
- start()、interrupt()、stop()、suspend()、resume()等方法能够改变线程的执行状态,都是因为其有对应的native同操作系统进行交互。
类级别的锁,保证线程安全性和唯一性
/* For generating thread ID */
private static long threadSeqNumber;
tid = nextThreadID();
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
public
class Thread implements Runnable {
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
init(group, target, name, stackSize);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name.toCharArray();
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 (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();
}
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 */
}
}
}
**private native void start0();**
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();
}
@Override
public void run() {
if (target != null) {
target.run();
}
}
}
3 ThreadGroup类
线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组。允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。
一般程序启动都至少有两个线程组:system线程组(parent=null),有JVM实例化,其做为main线程组的parent。
每个线程在调用构造函数的时候,必须绑定一个线程组,默认其获取实例化该线程对象的线程的线程组,大部分情况下都为main线程组。并且会调用线程组的g.addUnstarted();将未启动的线程数量+1。在调用线程的start方法时,group.add(this);将启动的线程放thread 数组中threads[nthreads] = t; 并且将启动线程+1,未启动线程-1;nthreads++;nUnstartedThreads–;
4 ThreadFactory类
ThreadFactory是一个工厂类,用于产生新的线程。
其中比较重要的是:
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = “pool-” +
poolNumber.getAndIncrement() +
“-thread-“;
group用于定义管理该线程工厂产生的线程的线程组,大部分时候采用默认值即main线程组。
namePrefix :表明线程的名字,一般在实现自己的线程工厂的时候,需要采用有意义的线程池名字,在调试的时候能够比较好的区分。
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}