Thread类中常用方法使用与源码解析
- getName() 获取线程名
private volatile String name;
/······/
public final String getName() {
return name;
}
获取一个线程的名称,是被volatile 修饰的线程安全的属性;
- setName (String)修改线程名
线程名称可以在线程被初始化得时候赋值,也可以初始化完成后使用set方法进行赋值
public final synchronized void setName(String name) {
//确定当前运行的线程是否有权限修改这个线程,没有权限会抛出SecurityException异常
checkAccess();
//名称为空抛出空指针异常
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
//确保是处在运行状态
if (threadStatus != 0) {
// 设置名称
setNativeName(name);
}
}
- getPriority 获取线程优先级
- setPriority (int)修改线程优先级
Java中规定线程优先级是1-10的整数,较大的优先级能提高该线程被cpu调度的几率,线程中给了三个预设的1,5,10(不太推荐用优先级,被推荐的不是很明显)
/**
* 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;
- getState() 获取线程状态
- Java中线程状态是用6个enum表示,分别是:
public enum State {
/**
* 尚未启动的线程的线程状态
*/
NEW,
/**
* 可运行线程的线程状态
*/
RUNNABLE,
/**
* 处于阻塞状态的线程
*/
BLOCKED,
/**
*等待线程的线程状态
*/
WAITING,
/**
*指定等待时间的等待线程
*/
TIMED_WAITING,
/*
*终止线程的线程状态
*/
TERMINATED;
}
- isInterrupted( )判断是否被打断,不会清楚打断标记
public boolean isInterrupted() {
// 是否清除打断标记设置为false,不清除打断标记
return isInterrupted(false);
}
- isAlive()线程是否存活(未运行完毕)
- interrupt() 打断线程
如果被打断的线程正在sleep,wait,join会导致被打断的线程抛出InterruptedException,并清除打断标记,如果打断的正在运行的线程,则会设置打断标记,park的线程被打断,也会设置打断标记
public void interrupt() {
// 是否是当前线程与检查线程主人
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
// 设置线程打断标记
interrupt0();
b.interrupt(this);
return;
}
}
interrupt0();
}
测试代码
结果:
- static interrupted()
判断当前线程是否被打断 会清除打断标记
//调用当前线程的isInterrupted方法清除打断标记
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
- static currentThread()获取当前正在执行的线程
- static sleep(long) 让当前正在执行的线程休眠n毫秒,休眠时让出cpu的时间片给其他线程
- 调用sleep会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
- 其他线程可以使用 interrupt()方法打断正在睡眠的线程,这时 sleep 方法就会抛出 InerruptedException
- 睡眠后的线程未必会立刻得到执行,进入runnable状态,会排队等执行
- 建议用TimeUnit的sleep代替Thread的sleep来获得更好的可读性,例:TimeUnit.SECONDS.sleep(1);
举例:防止CPU占用太多
yield
1.调用yield让当前线程从Running进入Runnable就绪状态,然后调度执行其他线程
2.具体实现依赖于操作系统的任务调度器
线程优先级
线程优先级会提示调度器优先调度该线程,但是调度器可以忽略它;
如果cpu比较忙,那个优先级高的线程会获得更多的时间片,但cpu闲时,优先级几乎没有用
死循环使用优先级时:
设置yiled时:
Join
调用该方法的线程等待该方法所属线程结束后继续运行,
比如main线程调用thread1的join方法,main线程会等待join线程执行完才会继续执行;
多join情况下:
新建线程类
执行测试代码
结果: