类图

请输入图片描述

Thread实现了Runnable接口这点一定牢记,在多线程编程中大部分都是使用Runnable传入Thread来完成的

类前注释

线程是程序中的执行线程。 Java虚拟机允许应用程序具有多个并行运行的执行线程。

JVM运行多线程运行

每个线程都有优先级。具有更高优先级的线程是优先于优先级较低的线程执行。每个线程可能(也可能不)被标记为守护程序。当运行中的线程又创建了线程对象时,被创建的线程对象的优先级等于创建者线程的优先级,并且当且仅当是创建线程是一个守护进程时它才会是守护进程。


子线程的优先级等于父线程的优先级;
子线程为守护线程的前提是父线程也是守护线程。

Java虚拟机启动时,通常只有一个非守护线程(通常调用名为main的某些指定类)。JVM遇到以下任何一个情况发生将会停止线程的执行:
    1、成功调用Runtime.getRuntime().exit(0);
    2、所有非守护线程已经结束了。线程结束的可能是run方法执行完成,又或者线程抛出了异常。

有两种方法可以创建新的线程。一个是声明一个类的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();

实现线程有两种方式:继承Thread类和实现Runnable接口

每个线程都有一个标识名。多个线程可以具有相同的名称。如果在创建线程时未指定名称,则会为其生成一个新名称。
除非另有说明,否则将null传递给此类中的构造函数或方法将导致抛出NullPointerException。

成员变量

private volatile String name;
private int            priority;
private Thread         threadQ;
private long           eetop;
private boolean     daemon = false;
private boolean     stillborn = false;
private Runnable target;
private ThreadGroup group;
private ClassLoader contextClassLoader;
private AccessControlContext inheritedAccessControlContext;
private static int threadInitNumber;
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
private long stackSize;
private long nativeParkEventPointer;
private long tid;
private static long threadSeqNumber;
private volatile int threadStatus = 0;
volatile Object parkBlocker;
private volatile Interruptible blocker;
private final Object blockerLock = new Object();

public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;

构造方法

/**
 * 分配一个新的线程对象。这个构造方法和Thread(null, null, gname)具有相同的效果线程,其中gname是新生成的名字。 
 * 自动生成的名称的形式的"Thread-"+ n,其中n是一个整数。
 */
public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

/**
 * 分配一个新的线程对象。这个构造方法和Thread(null, target, gname)具有相同的效果线程,
 * 其中gname是新生成的名字。 自动生成的名称的形式的"Thread-"+ n,其中n是一个整数。
 * @param  target
 *         当线程启动时target的run方法将会被调用。如果target为空则run方法不执行。
 */
public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

public Thread(String name) {
    init(null, null, name, 0);
}

/**
 * 分配一个新的线程对象,它具有target作为其运行对象,
 * 指定的name作为其名称,由group属性指定的线程组,并设置指定的堆栈大小。
 *
 * 此构造方法和Thread(ThreadGroup, Runnable, String)是相同的,除了它允许指定的线程堆栈大小。
 * 堆栈大小是虚拟机要为此线程的堆栈分配的地址空间的大概字节数。stackSize参数的效果在很大程度上取决于平台。
 *
 * 在某些平台上,为stackSize参数指定更高的值可能会允许线程在引发StackOverflowError之前实现更大的递归深度。
 * 类似地,指定一个较低的值可能允许并发存在更多数量的线程,而不会引发OutOfMemoryError(或其他内部错误)。
 *
 * 虚拟机可以自由地将stackSize参数作为建议。
 * 如果平台的指定值过低,则虚拟机可能会使用某些平台特定的最小值;
 * 如果指定的值过高,则虚拟机可能会使用特定于平台的最大值。
 * 同样,虚拟机可以根据需要随意向上或向下舍入指定的值(或完全忽略它)。
 *
 * 为stackSize参数指定零值将导致此构造函数的行为与Thread(ThreadGroup,Runnable,String)构造函数完全相同。
 *
 * 由于此构造函数的行为与平台有关,因此在使用它时应格外小心。执行给定计算所需的线程堆栈大小可能会因一个JRE实现而异。 
 * 鉴于这种变化,可能需要仔细调整堆栈大小参数,并且可能需要为每个运行应用程序的JRE实现重复进行调整。
 *
 * 实现注意事项:鼓励Java平台实现者记录其实现相对于stackSize参数的行为。
 *
 *
 * @param  group
 *         线程组。如果为空且存在安全管理器,则由SecurityManager.getThreadGroup()确定。如果没有SecurityManager或SecurityManager
 *         如果没有SecurityManager或SecurityManager.getThreadGroup()返回null,则组设置为当前线程的线程组。
 *
 * @param  target
 *         启动此线程时调用target的run方法。如果为null则调用此线程的run方法。
 *
 * @param  name
 *         新线程的名字
 *
 * @param  stackSize
 *         新线程所需的堆栈大小,或0表示忽略此参数。
 *
 * @throws  SecurityException
 *          如果当前线程无法在指定的线程组中创建线程抛出此异常
 *
 * @since 1.4
 */
public Thread(ThreadGroup group, Runnable target, String name,
              long stackSize) {
    init(group, target, name, stackSize);
}

/**
 * 继承给定的AccessControlContext创建一个新线程。这不是一个公共的构造函数。
 */
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(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);
}

关注前面几个简单的即可,太复杂的不常用(也许是我菜~_~)

Last modification:August 10th, 2020 at 12:18 am
如果觉得我的文章对你有用,请随意赞赏