简介
直奔主题,从源码解析Thread的用法以及多线程的使用
public class Thread
extends Object
implements Runnable
// Runnable接口定
public interface Runnable {
public abstract void run();
}
//Thread重写run方法
@Override
public void run() {
if (target != null) {
//private Runnable target;最终调Runable接口实现类的run方法
target.run();
}
}
构造方法解析
/**
*分配新的线程对象。此构造函数与Thread(null、null、gname)具有相同的效果,
*其中gname是线程名称。自动生成的名称的格式为“Thread-”+n,其中n是整数。
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
o
//这里交代可以用子类继承Thread,即Thread t=new SonThread();并重写Thread的run方法,调用start方法开启线程
/**
* 分配新的线程对象。此构造函数与Thread(null、target、gname)具有相同的效果,其中
* gname是新生成的名称。自动生成的名称的格式为“Thread-”+n,其中n是整数。
*
* @param target Runable接口实例
*
*/
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
//这里交代可以用Runable接口实例作为参数给Threa,Runable接口实例实现run方法,
从构造方法可以看出实现线程的方式只有一种,那就是new一个Threa类出来,只是run方法来源不同,一个实现Runable接口run方法,一个是重写Thrad的run方法,但是无论如何Runable接口都是实现线程的顶层接口,除此之外表面上线程池、定时器等工具类也可以创建线程,但是底层都是通过new Thread类来实先线程,官方java语言规范明确记载new Threa()是实现线程的唯一方法。
在博客多线程编程知识点一有详细介绍如何创建多线程
重要方法
/**
* 返回对当前正在执行的线程对象的引用。
*
* @return the currently executing thread.
*/
@FastNative
public static native Thread currentThread();
/**
* 返回当前线程的名称
*
* @return this thread's name.
* @see #setName(String)
*/
public final String getName() {
return name;
}
通常的用法是 Thread.currentThread().getName()
/**
*
* 是线程休眠指定时间,但是不释放锁的控制权,时间到了苏醒继续试图获取CPU执行权
*
* @param 参数为一个毫秒值
*
* @throws IllegalArgumentException
* 如果参数为负数
*
* @throws InterruptedException
* 如果有线程中断了当前线程。引发此异常时,当前线程的中断状态将被清除。
*/
public static void sleep(long millis) throws InterruptedException {
Thread.sleep(millis, 0);
}
/**
*
*
*通常在其他线程调用此方法。来中断线程
*
*如果此线程在调用对象类的wait()、wait(long)或wait(long,int)方法
*或该类的join()、join(long)、join(long,int)、sleep(long)或
*sleep(long,int)方法时被阻止,则其中断状态将被清除,并将接收到InterruptedException。
*
*
* 此外将设置中断状态
* 中断不活动的线程没有任何效果
*
* @throws SecurityException
* 自己中断自己,如果当前线程无法修改此线程
*
* @revised 6.0
* @spec JSR-51
*/
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
nativeInterrupt();
b.interrupt(this);
return;
}
}
nativeInterrupt();
}
/**
* T测试线程是否被中断,不会清除中断状态
*
*中断返回true,否则返回false
*
* @see #interrupted()
* @revised 6.0
*/
@FastNative
public native boolean isInterrupted();
/**
*测试线程是否被中断,并清除中断状态,如果被中断返回true否则返回false,调用两次得到结果不一样
*
* @see #isInterrupted()
* @revised 6.0
*/
@FastNative
public static native boolean interrupted();
/**
* 在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。
*
*
* @throws InterruptedException
* 如果任何线程中断了当前线程。当抛出此异常时,当前线程的中断状态将被清除。
*/
public final void join() throws InterruptedException {
join(0);
}
/**
* 在A线程中调用了B线程的join()方法时,表示只有当B线程执行完指定的时间后,A线程才能继续执行。
*
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
*
* @param millis
* 等待时间
*
* @throws IllegalArgumentException
* 参数小于0
*
* @throws InterruptedException
* 如果任何线程中断了当前线程。当抛出此异常时,当前线程的中断状态将被清除。
*/
public final void join(long millis) throws InterruptedException {
synchronized(lock) {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
//当参数为0直接运行当前线程
lock.wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
//阻塞当前线程,直到时间到了
lock.wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
}
/**
* 休眠当前线程.
*
*这方法已经被启用,因为休眠后不释放锁,容易死锁
*
*/
//过时的
@Deprecated
public final void suspend() {
throw new UnsupportedOperationException();
}
/**
* 过时方法,此方法仅用于与suspend()一起使用,唤醒一个线程,
*/
@Deprecated
public final void resume() {
throw new UnsupportedOperationException();
}
/**
*
*这个方法过时了,用来停止线程(导致线程运行一半突然停止)没办法完成一个基本单位的操作,同时释放锁,这样导致线程不安全
*/
@Deprecated
public final void stop() {
stop(new ThreadDeath());
}
/**
*
* 使得当前线程放弃CPU执行权,让线程从运行状态到就绪状态,但是不释放锁资源,状态任然是可运行状态
* 如果某一个线程是不太紧急的线程,可以在编写时调用yield()这样会让其它线程得到更多的执行机会
*/
public static native void yield();
总结一下,如果要暂停线程推荐使用 interrupt()去通知目标线程是否中断执行,而不是stop、suspend和ruseme强行中断,详情请看多线程核心知识(二)
Object类和线程先关的方法
/**
*使当前线程等待,直到另外一个线程调用此对象的notify()方法或notifyAll()方法唤醒去继续获得cpu执行
*权,或者等待指定时间重新去继续获得cpu执行权,调用此方法会释放锁资源
*
* @param millis 时间毫秒值
* @throws IllegalArgumentException 如果参数为负数
*
* @throws IllegalMonitorStateException
* 如果当前线程不是对象监视器的所有者。
* @throws InterruptedException
* 如果被其他线程打断报异常,而且清除中断状态
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final void wait(long millis) throws InterruptedException {
wait(millis, 0);
}
/**
* 引起当前线程等待,释放锁,直到另一个线程为此对象调用notify()方法或notifyAll()方法。线程继续设
* 法获得执行权
*
* 此方法只能由锁的获得者的线程调用
*
* @throws IllegalMonitorStateException 如果当前线程不是对象监视器的所有者。
* @throws InterruptedException
* 线程被其他线程打断抛出异常,并清除中断状态
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
@FastNative
public final native void wait() throws InterruptedException;
/**
* 随机唤醒等待集中某一个线程
*
* @throws IllegalMonitorStateException 如果当前线程不是此对象监视器的所有者。
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
*/
@FastNative
public final native void notify();
/**
* 唤醒等待集中所有线程
*
*
* @throws IllegalMonitorStateException 如果当前线程不是此对象监视器的所有者。
*
* @see java.lang.Object#notify()
* @see java.lang.Object#wait()
*/
@FastNative
public final native void notifyAll();