线程状态转换
线程控制基本方法
方法 | 功能 |
---|---|
isAlive() | 判断线程是否终止 |
getpriority() | 获得线程的优先级数值 |
setpriority() | 设置线程优先级数值 |
Thread.sleep() | 设置当前线程睡眠指定毫秒数 |
join() | 调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行 |
yield() | 让出CPU,让当前线程进入就绪队列等待调度 |
wait() | 当期线程进入对象的wait pool |
notify()/notifyAll() | 唤醒对象的wait pool中的一个/所有等待线程 |
sleep/join/yield方法
- sleep方法(暂停执行线程)
import java.io.*;
import java.util.*;
public class TestThread1 {
public static void main(String[] args) {
MyThread m = new MyThread();
Thread t = new Thread(m);
t.start();
try{
Thread.sleep(10000);//10秒钟
//在哪个线程中调用的sleep方法,就让哪个线程睡眠
}catch(InterruptedException e){}
t.interrupt();//打断睡眠线程
}
}
class MyThread implements Runnable{
public void run(){
while(true){
System.out.println("-----" + new Date() + "-----");
try{
Thread.sleep(1000);//1秒钟
}catch (InterruptedException e){
return;
}
}
}
}
改程序执行过程是:每隔一秒钟打印一次时间,打印10次(10秒钟过后),主线程被唤醒,执行interrupt方法,打断MyThread线程,因为Mythread线程被打断,sleep方法就会捕捉到异常,执行return,终止程序
这种终止线程的方式并不推荐,Thread类中的stop方法也是停止线程,但是也不推荐,推荐的方法写法
import java.util.*;
public class TestThread1 {
public static void main(String[] args) {
MyThread m = new MyThread();
Thread t = new Thread(m);
t.start();
try{
Thread.sleep(10000);
m.flag = false;
}catch(InterruptedException e){}
}
}
class MyThread implements Runnable{
boolean flag = true;
public void run(){
while(flag){
System.out.println("-----" + new Date() + "-----");
try{
Thread.sleep(1000);//1秒钟
}catch (InterruptedException e){
return;
}
}
}
}
- join方法(合并线程)
public class TestJoin {
public static void main(String[] args) {
MyThread t1 = new MyThread("t1");
t1.start();
try {
t1.join();
}catch(InterruptedException e) {}
for(int i = 1;i <= 10;i++)
System.out.println("i am main Thread");
}
}
class MyThread extends Thread{
MyThread(String s){
super(s);
}
public void run() {
for(int i = 1;i <= 10;i++)
System.out.println("i am " + getName());
try {
sleep(1000);
}catch(InterruptedException e){
return;
}
}
}
程序运行结果如下:
join会将线程添加到当前执行的线程中来执行,对于上述程序,会将MyThread线程添加到主线程中执行,MyThread线程执行完了,才会继续执行主线程
用一个图来解释上述程序的执行过程:
- yield方法(让出CPU,给其他线程执行的机会)
public class TestYield {
public static void main(String[] args) {
MyThread2 t1 = new MyThread2("t1");
MyThread2 t2 = new MyThread2("t2");
t1.start();
t2.start();
}
}
class MyThread2 extends Thread{
MyThread2(String s){
super(s);
}
public void run() {
for(int i = 1;i <= 15;i++) {
System.out.println(getName() + ":" + i);
if(i % 5 == 0)
yield();
}
}
}
程序执行过程见下图:
观察这个程序结果我们能发现,不论当前执行的线程是t1还是t2,每当到了5的倍数,下一次执行的一定是另一个线程,这就是yield方法的作用,让出当前CPU给其他线程
线程的优先级
线程的优先级用数字表示,范围从1到10,一个线程的默认优先级是5
- Thread.MIN_PRIORITY = 1
- Thread.MAX_PRIORITY = 10
- Thread.NORM_PRIORITY = 5
使用下述方法可以获得或设置线程对象的优先级
- int getPriority()
- void setPriority(int newPriority)
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 + 4);
t1.start();
t2.start();
}
}
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);
}
}