Thread的常用方法
- public final void setName(String name)
设置当前线程的名字 - public static Thread currentThread()
返回对当前正在执行的线程对象的引用 - public final String getName()
返回当前线程的名字
// 线程方法的介绍
class A extends Thread {
public void run() {
System.out.println("AAAA");
System.out.printf("%s在执行!\n", Thread.currentThread().getName());// Thread-0在执行!
}
}
public class TestThread {
public static void main(String[] args) {
A aa = new A();
aa.start()
System.out.println("BBBB");
System.out.printf("%s在执行!\n", Thread.currentThread().getName()); // main在执行
}
}
线程的控制
- 线程控制的基本方法
方法 | 功能 |
---|---|
isAlive() | 判断线程是否还“活”着,即线程是否还未终止 |
getPriority | 获得线程的优先级数值 |
setPriority() | 设置线程的优先级数值 |
Thread.sleep() | 将当前线程睡眠指定毫秒数 |
jion() | 当用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行 |
yield() | 让出CPU,当前线程进入就绪队列等待调度 |
wait() | 当前线程进入对象的wait pool |
notify() / notifyAll() | 唤醒对象的wait pool中的一个 / 所有等待线程 |
线程优先级
线程的优先级用数字来表示,范围从1到10。
主线程的缺省优先级是5,子线程的优先级默认与其父线程相同。
- Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪个线程来执行。
- 线程的优先级用数字来表示,范围从1到10,一个线程的缺省优先级是5.
Thread.MIN_PRIORITY = 1
Thread.MAX_PRIORITY = 10
Thread.NORM_PRIORITY = 5
- 使用下述线程方法获得或设置线程对象的优先级
int getPriority()
void setPriority(int newPriority)
通常高优先级的线程将先于优先级低的线程执行,但并不总是这样的,因此实际开发并不单纯依赖优先级来决定线程运行次序。
class T1 implements Runnable {
public void run() {
for (int i=0; i<100; ++i)
System.out.println("T1: " + i);
}
}
class T2 implements Runnable {
public void run() {
for (int i=0; i<100; ++i)
System.out.println("------T2: " + i);
}
}
public class TestPriority {
public static void main(String[] args) {
Thread t1 = new Thread(new T1());
Thread t2 = new Thread(new T2());
t1.setPriority(Thread.NORM_PRIORITY + 3);// t1 的优先级被设为8,比t2优先级5要大,所以线程t1先执行,执行完再执行t2进程
t1.start();
t2.start();
}
}
线程的休眠
- 线程休眠-----暂停执行当前运行中的线程,使之进入阻塞状态,待经过指定的“延迟时间”后再醒来并转入到就绪状态。
- Thread类提供的相关方法:
public static void sleep(long millis)
public static void sleep(long millis, int nanos)
- 由于是静态方法,可以由Thread直接调用
- sleep()方法会抛出InterruptedException异常,我们必须得对其进行捕捉
class A implements Runnable {
public void run() { // 2行
for (int i=0; i<10; ++i) {
System.out.println(Thread.currentThread().getName() + " " + i);
try {
Thread.sleep(1000); // 这里的Thread.sleep(1000)会抛出异常
// 所以必须得进行捕捉,不能在2行的后面添加throws Exception
} catch (Exception e) {
}
}
}
}
public class TeatSleep {
public static void main(String[] args) {
A aa = new A();
Thread tt = new Thread(aa);
tt.start();
}
}
无论是继承Thread类的run方法还是实现了Runnable接口的run方法,都不能抛出任何异常
class A implements Runnable {
public void run() // throws Exception { // 注释符不能去掉,否则编译会报错
}
}
class B extends Thread {
public void run() // throws Exception { // 注释符不能去掉,否则编译会报错
}
}
原因:重写方法抛出异常的范围不能大于被重写方法排除的异常范围
线程的让步
- 让出CPU,给其他线程执行的机会
- 让运行中的线程主动放弃当前获得的CPU处理机会,但不是使该线程阻塞,而是使之转入就绪状态。
public static void yield()
class MyThread implements Runnable {
public void run() {
for (int i=1; i<=100; ++i) {
System.out.println(Thread.currentThread().getName() + ":" + i);
if (0 == i%10)
Thread.yield();
}
}
}
public class TestYield {
public static void main(String[] args) {
MyThread mt = new MyThread();
Thread t1 = new Thread(mt);
Thread t2 = new Thread(mt);
t1.setName("线程A");
t2.setName("线程B");
t1.start();
t2.start();
}
}
线程的串行化
- 在多线程程序中,如果在一个线程运行的过程中要用到另一个线程的运行结果,则可进行线程的串行化处理
public final void jion() throws InterruptedException
class MyRunner implements Runnable {
public void run() {
for (int i=0; i<50; i++)
System.out.println("子线程:" + i);
}
}
public class TestJoin {
public static void main(String[] args) {
MyRunner r = new MyRunner();
Thread t = new Thread(r);
t.start();
try {
t.jion(); // 7行
} catch(InterruptedException e ) {
e.printStackTrace();
}
for (int i=0; i<50; i++)
System.out.println("主线程:" + i);
}
}
7行的 t.jion()暂停当前正在执行t.jion()的线程,直到t所对应的线程运行终止之后,当前线程才会获得继续执行的机会
注意:t.jion()不是暂停t对象所对应的线程
线程的挂起和恢复
- 线程挂起----暂时停止当前运行中的线程,使之转入阻塞状态,并且不会自动恢复运行。
- 线程恢复----- 使得一个已挂起的线程恢复运行。
- Thread类提供的相关方法
public final void suspend()
public final void resume()
- suspend()方法挂起线程时并不释放其锁定的资源,这可能会影响其他线程的运行,且容易导致线程的死锁,已经不提倡使用
生命周期控制
- 如何结束一个线程
class A implements Runnable {
private boolean flag = true;
public void run() {
while (flag)
System.out.println("AAAA");
}
public void shutDown() {
this.flag = false;
}
}
public class TestShutThread {
public static void main(String[] args) {
A aa = new A();
Thread tt = new Thread(aa);
tt.start();
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
aa.shutDown();
}
}