Thread&Runable
Thread
public class Thread implements Runnable{
}
Thread构造方法
//无参构造方法,自动生成name
public Thread()
//字符串构造方法,传入一个字符串给线程命名
//可以用Thread类的get/setName方法对name进行访问和修改
public Thread(String name)
//传入Runnable接口实现
public Thread(Runnable target)
//传入一个线程组、一个Runnable接口实现
//其中线程组中的基本单元既可以是线程也可以是线程组,进而组成一棵线程树
//除初始线程组之外,每个线程组有一个父线程
public Thread(ThreadGroup group, Runnable target)
//传入线程组、线程名
public Thread(ThreadGroup group, String name)
//传入Runnable接口实现,传入线程名
public Thread(Runnable target, String name)
//线程组、线程名、Runnable接口实现三者都传入
public Thread(ThreadGroup group, Runnable target, String name)
//多了一个stackSize,用于指定该线程申请的堆栈大小,不指定时默认为0
//对于stackSize这个值如何使用,则由虚拟机自行决定
//有些虚拟机会忽略这个值
public Thread(ThreadGroup group, Runnable target, String name, long stackSize)
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();
}
一个对象实现Runnable接口来创建线程,启动这个线程导致在单独执行的线程中调用对象的run方法。
区别
实现多线程可以采用继承Thread类也可以采用实现Runnable接口,不过常用实现Runnable接口的方法,原因是:
- 可以避免单继承的局限性。Java中的继承,支持单继承、多重继承(A继承B,B继承C…..,N继承M),不支持多继承(C同时继承A和B)。当自己的类继承了Thread类,就无法去继承其他类。
- 增加程序的健壮性,实现解耦,降低耦合度,核心方法实现Runnable接口的类可以被多个线程共享,而且任务代码与线程独立,线程的任务代码和线程的启动代码分离。
- 线程池只能放入实现Runnable或Callable类的线程,自己写的继承自Thread的类无法放入线程池。实现Runnable涉及到资源共享的问题,而继承Tread的类资源相对独立。
Start&Run
Start 启动方法
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the 'run' method of this thread.
*
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the start method)
* and the other thread (which executes its run method).
*
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* @exception IllegalThreadStateException if the thread was already
* started.
* @see #run()
* @see #stop()
*/
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 */
}
}
}
-
使新线程开始执行,JVM调用该线程的start方法
- 执行结果是两个线程同时执行
- 当前线程在调用新线程的start之后继续执行
- 新线程执行run方法
-
每次启动线程是不合法的。特别是,线程一旦完成执行,就不能重复启动。
-
主方法现场或系统组进程,无法调用start方法
-
threadStatus为0时,代表thread的状态为new
-
start0()是一个native方法。
native方法:
- native与访问控制符前后关系不受限制
- native关键字必须在返回值之前
- native方法一般为非抽象方法
- native方法在异地实现
native方法常作为java调用非java的接口:
- native方法是java方法
- native方法声明在java代码中
- native方法在异地用非java代码实现
- java在不同平台通过调用不同的native方法实现对操作系统的访问
Run 任务方法
/**
* If this thread was constructed using a separate
* Runnable run object, then that
* Runnable object's run method is called;
* otherwise, this method does nothing and returns.
*
* Subclasses of Thread should override this method.
*
* @see #start()
* @see #stop()
* @see #Thread(ThreadGroup, Runnable, String)
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
区别
- start方法是启动一个线程,在新线程中执行run方法中的代码,结果是同时执行原线程和新线程
- run方法不会启动新线程,在同一线程中进行方法调用,结果是只有主线程
- Runnable作为Thread的target,Runnable中的run方法作为Thread的执行体。实际的线程对象是Thread实例,只不过Thread实例负责执行target的run方法。而线程的启动都要调用Thread实例的start方法。
Tips
- Thread.currentThread()是一个静态native方法,可以直接调用currentThread()返回一个Thread对象来获取当前线程,尤其是当没有当前线程的引用时,可以用这个方法对当前线程进行访问和设置。
- Thread的Priority默认为5,最小为1,最大为10,由Thread类中MIN_PRIORITY=1,NORM_PRIORITY=5,MAX_PRIORITY=10三个final static控制
- final关键字
- final修饰的属性表明是一个常数
- final修饰的方法表示在子类中不能被重写
- final修饰的类表示不能被继承
- final修饰的引用不可被修改,但引用的对象可以被修改
- static关键字
- static与具体对象无关,强调只有一个
- 不创建对象也能调用static修饰的属性和方法
- this&super
- 与具体对象有关
- static final
- 两关键字顺序没有影响,可以是static final,也可以是final static
- static final表示值只有一个,而且是常量