本篇讲述线程使用的六大常用方法:sleep()、join()、yield()、setDaemon()、setPriority () & getPriority()、getState()
方法一:sleep()
- sleep (时间)指定当前线程阻塞的毫秒数
- sleep存在异常InterruptedException
- 每一个对象都有一个锁,sleep不会释放锁
- 使线程停止运行一段时间,将处于阻塞状态
- 如果调用了sleep方法之后,没有其他等待执行的线程,这个时候当前线程不会马上恢复执行!
- 线程由运行状态进入阻塞状态,时间一到,再回到预备状态,等待CPU的重新调度。
之前我们用sleep() 模拟了网络延时,可以放大发生问题的可能性;还模拟了龟兔赛跑中兔子的休息的过程;我们今天来实现一个简单的倒计时功能。
代码实现
public class BlockedSleep3{
public static void main(String[] args) throws InterruptedException {
//倒计时10s
int num = 10;
for(int i=num;i>0;i--){
System.out.println(i);
Thread.sleep(1000);
}
System.out.println("over");
}
}
结果
方法二:join()
join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞
代码实现
public class BlockedJoin1 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
for(int i=0;i<100;i++){
System.out.println("lambda..."+i);
}
});
t.start();
for(int i=0;i<100;i++){
if(i==20){
//被插队
t.join();
}
System.out.println("main..."+i);
}
}
}
结果
我们可以看到main被阻塞
我们可以指定毫秒数,其他线程在规定时间内都没能完成时,就不再排队。
方法三:yield()
- 线程直接由运行状态跳回预备状态。
- 让当前正在执行线程暂停,不是阻塞线程,而是将线程转入就绪状态
- 调用了yield方法之后,如果没有其他等待执行的线程,此时当前线程就会马上恢复执行!
代码实现
public class YieldDemo1 {
public static void main(String[] args) {
MyYield my = new MyYield();
new Thread(my,"a").start();
new Thread(my,"b").start();
}
}
class MyYield implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getName()+"-->start");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"-->end");
}
}
结果
我们可以看到,礼让后不一定按照顺序执行,礼让只是让其返回就绪状态,重新等待CPU调度。
方法四:setDaemon()
线程分为用户线程和守护线程。
虚拟机必须确保用户线程执行完毕。虚拟机不用等待守护线程执行完毕,如后台记录操作日志、监控内存使用等。
- 可以将指定的线程设置成后台线程,守护线程
- 创建用户线程的线程结束时,后台线程也随之消亡
- 只能在线程启动之前把它设为后台线程
代码实现
public class DaemonTest {
public static void main(String[] args){
God god = new God();
You you = new You();
Thread t = new Thread(god);
t.setDaemon(true); //将用户线程调整为守护
t.start();
new Thread(you).start();
}
}
class You implements Runnable{
public void run(){
for(int i=1;i<=365*100;i++){
System.out.println("happy life...");
}
System.out.println("over!");
}
}
class God implements Runnable{
public void run(){
while(true){
System.out.println("bless you...");
}
}
}
结果
为用户线程服务,JVM停止不用等待守护线程执行完毕。
方法五:setPriority () & getPriority()
- 线程的优先级代表的是概率
- 范围从1到10,默认为5
Java提供:一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪个线程来执行。
代码实现
public class PriorityTest {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getPriority());
MyPriority mp = new MyPriority();
Thread t1 = new Thread(mp);
Thread t2 = new Thread(mp);
Thread t3 = new Thread(mp);
Thread t4 = new Thread(mp);
Thread t5 = new Thread(mp);
Thread t6 = new Thread(mp);
//设置优先级要在启动之前
t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(2);
t3.setPriority(4);
t4.setPriority(6);
t5.setPriority(8);
t6.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}
class MyPriority implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
结果
- NORM_PRIORITY 5 默认
- MIN_PRIORITY 1
- MAX_PRIORITY 10
优先级高的可能执行的时间片多一些,执行的早一点,不代表先后顺序。
方法六:getState()
代码实现
用来观察线程的状态
public class AllState {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
for(int i=0;i<5;i++){
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("...");
});
//观察状态
State state = t.getState();
System.out.println(state); //NEW
//观察状态
t.start();
state = t.getState();
System.out.println(state); //RUNNABLE
while(state!=Thread.State.TERMINATED){
Thread.sleep(200);
state = t.getState(); //TIMED_WAITING
System.out.println(state);
}
}
}
结果
七、补充
方法 | 功能 |
---|---|
isAlive() | 判断线程是否还活着(是否在运行) |
setName() | 给线程起一个名字 |
getName() | 获取线程的名字 |
currentThread() | 取得当前正在运行的线程对象 |