Java线程三:sleep()方法;join()方法;线程的优先级

本文详细介绍了Java线程控制的两个关键方法:sleep()和join(),以及线程优先级的概念。sleep()方法用于让线程暂停执行指定时间,而join()方法则使得调用线程等待目标线程执行完毕后再继续。线程优先级则影响线程获取CPU执行权的顺序,但并不绝对决定执行顺序。示例代码展示了这些方法的使用和效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.sleep()方法

●sleep()方法使线程由正在运行状态转换到阻塞状态;线程暂时放弃CPU使用权;

●sleep()方法是Thread类中的方法;

●public static void sleep(long  millis):静态方法,可直接用Thread类名字去调用;millis:毫秒,1000ms == 1s;

●sleep()方法:应用场景可能有(1)需要计时的情况,每隔一定时间显示一下时间等;(2)对于一些需要定期刷新数据而不是一直刷新数据的情况;

●需要注意一个线程到底能不能执行,或者说一个线程到底能不能“暂停”,不仅和sleep()方法有关,还与CPU是否可用有关;当一个线程sleep()方法执行完毕后,线程只是进入了可运行状态,该线程必须获得CPU的使用权才能真正开始执行。(所以,sleep()方法应用在严格的时钟计算时,可能会存在误差);

……………………………………………………

示例程序:

注:sleep()方法需要捕获异常;

       sleep()方法的具体应用场景和应用技巧需要在实际开发中慢慢积累

class MyThread implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i = 1;i<=15;i++){
			System.out.println(Thread.currentThread().getName()+"执行第"+i+"次。");
			try {
				// 为什么要捕获异常:在线程执行sleep()方法时候,可能会因为某些原因线程突然被打断,要处理一下这种异常
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}	
}


public class SleepDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread mt = new MyThread();
		Thread thread = new Thread(mt);
		thread.start();
		//Thread thread1 = new Thread(mt);
		//thread1.start();
	}
}

2.join方法

●join()方法使线程由正在运行状态转换到阻塞状态;线程暂时放弃CPU使用权;

●join()方法也是Thread类的方法;

●public final void join():是个final方法,字面理解join是加入、抢先进入的意思;

●一个线程调用了join()方法,那么这个线程获得了优先执行权,其他线程需要等待该线程执行完毕后才能执行;join()方法是一种抢占资源的方式;

……………………………………………………

示例程序:join(),无参形式,调用join()方法线程执行结束后,其他线程才会执行。

注:join()方法也需要捕获异常;

       join()方法的具体应用场景和应用技巧需要在实际开发中慢慢积累;

class MyThread1 extends Thread{
	public void run(){
		for(int i = 1;i<=10;i++){
			System.out.println(getName()+"正在执行"+i+"次。");
		}
	}
}

public class JoinDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread1 mt = new MyThread1();
		mt.start();
		try {
			// 为什么要捕获异常:在线程执行join()方法时候,可能会因为某些原因线程突然被打断,要处理一下这种异常
			mt.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for(int i = 1;i<=10;i++){
			System.out.println("主线程运行第"+i+"次。");
		}
		System.out.println("主线程运行结束。");
	}
}

输出结果:可以发现,因为mt线程调用了join()方法,所以mt线程获得了优先执行权;

Thread-0正在执行1次。
Thread-0正在执行2次。
Thread-0正在执行3次。
Thread-0正在执行4次。
Thread-0正在执行5次。
Thread-0正在执行6次。
Thread-0正在执行7次。
Thread-0正在执行8次。
Thread-0正在执行9次。
Thread-0正在执行10次。
主线程运行第1次。
主线程运行第2次。
主线程运行第3次。
主线程运行第4次。
主线程运行第5次。
主线程运行第6次。
主线程运行第7次。
主线程运行第8次。
主线程运行第9次。
主线程运行第10次。
主线程运行结束。

若是,mt线程没有调用join方法:

class MyThread1 extends Thread{
	public void run(){
		for(int i = 1;i<=10;i++){
			System.out.println(getName()+"正在执行"+i+"次。");
		}
	}
}

public class JoinDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread1 mt = new MyThread1();
		mt.start();
//		try {
//			// 为什么要捕获异常:在线程执行join()方法时候,可能会因为某些原因线程突然被打断,要处理一下这种异常
//			mt.join();
//		} catch (InterruptedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		for(int i = 1;i<=10;i++){
			System.out.println("主线程运行第"+i+"次。");
		}
		System.out.println("主线程运行结束。");
	}
}

输出结果:mt线程没有调用join()方法时,mt线程和主线程随机获取CPU使用权。

主线程运行第1次。
Thread-0正在执行1次。
主线程运行第2次。
Thread-0正在执行2次。
主线程运行第3次。
Thread-0正在执行3次。
Thread-0正在执行4次。
主线程运行第4次。
主线程运行第5次。
主线程运行第6次。
主线程运行第7次。
主线程运行第8次。
主线程运行第9次。
主线程运行第10次。
主线程运行结束。
Thread-0正在执行5次。
Thread-0正在执行6次。
Thread-0正在执行7次。
Thread-0正在执行8次。
Thread-0正在执行9次。
Thread-0正在执行10次。

……………………………………………………

示例程序:join(long millis):调用join(long millis)方法的线程,其优先执行权只能维持一定时间,一定时间过后丧失优先权,和其他线程一样随机获取执行权

class MyThread1 extends Thread{
	public void run(){
		for(int i = 1;i<=300;i++){
			System.out.println(getName()+"正在执行"+i+"次。");
		}
	}
}

public class JoinDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread1 mt = new MyThread1();
		mt.start();
		try {
			// 为什么要捕获异常:在线程执行join()方法时候,可能会因为某些原因线程突然被打断,要处理一下这种异常
			mt.join(2);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for(int i = 1;i<=10;i++){
			System.out.println("主线程运行第"+i+"次。");
		}
		System.out.println("主线程运行结束。");
	}
}

输出结果:输出结果截取部分,由执行结果可以发现join(long millis)方法作用。

Thread-0正在执行66次。
Thread-0正在执行67次。
Thread-0正在执行68次。
Thread-0正在执行69次。
主线程运行第1次。
Thread-0正在执行70次。
Thread-0正在执行71次。
主线程运行第2次。
Thread-0正在执行72次。
主线程运行第3次。
Thread-0正在执行73次。
主线程运行第4次。
Thread-0正在执行74次。
主线程运行第5次。
Thread-0正在执行75次。
主线程运行第6次。
Thread-0正在执行76次。
主线程运行第7次。
Thread-0正在执行77次。
主线程运行第8次。
Thread-0正在执行78次。
Thread-0正在执行79次。
Thread-0正在执行80次。
Thread-0正在执行81次。
Thread-0正在执行82次。
Thread-0正在执行83次。
Thread-0正在执行84次。
Thread-0正在执行85次。
Thread-0正在执行86次。

3.线程的优先级

●Java为线程提供了10个优先级,优先级可以使用整数1-10表示,超过这个范围会抛出异常;数字越大,表示优先级越高;

●main()方法的线程(主线程)默认优先级是5;

●除了用数字表示优先级,还可以用优先级常量来表示优先级:

          MAX_PRIORITY:线程的最高优先级10;

          MIN_PRIORITY:线程的最低优先级1;

          NORM_PRIORITY:线程的默认优先级5;

●Thread类提供了获取线程优先级的方法、和设置线程优先级的方法:

●线程的优先级只是提供了一个优先级别,优先级高的线程不一定非得先执行,是否先执行与CPU状态,系统状态等很多因素有关;即其执行还是有一定的随机性的;

……………………………………………………

示例程序:主要就是setPriority()方法、和getPriority()方法;

class MyThread2 extends Thread{
	private String name;
	public MyThread2(){}
	public MyThread2(String name){
		// 注:给线程自定义名字,需要调用Thread的有参构造才行,即需要super(name)才行;
		// 这儿的name只是一个方便观察的变量,其实并不是线程的name.
		this.name = name;
	}
	public void run(){
		for(int i = 1;i<=10;i++){
			System.out.println("线程"+name+"正在执行"+i);
		}
	}
}

public class PriorityDemo {

	public static void main(String[] args) {
		// 获取主线程的优先级
		int mainPriority = Thread.currentThread().getPriority();
		//System.out.println("主线程的优先级为:"+mainPriority);
		MyThread2 mt1 = new MyThread2("线程1");
		MyThread2 mt2 = new MyThread2("线程2");
		int mt1Priority = mt1.getPriority();
		//System.out.println("mt1线程的优先级为:"+mt1Priority);
		// 设置mt1线程的优先级
		//mt1.setPriority(10);
		//或者这样设置mt1的优先级
		mt1.setPriority(Thread.MAX_PRIORITY);
		mt2.setPriority(Thread.MIN_PRIORITY);
		mt1.start();
		mt2.start();
	}
}

输出结果:可以发现,并不是高优先级的线程先执行完后低优先级的线程才执行,其任然存在一定的随机性;

                  换句话说,优先级高的程序并不一定会比优先级低的线程先运行;

线程线程1正在执行1
线程线程2正在执行1
线程线程1正在执行2
线程线程2正在执行2
线程线程1正在执行3
线程线程2正在执行3
线程线程1正在执行4
线程线程1正在执行5
线程线程1正在执行6
线程线程1正在执行7
线程线程1正在执行8
线程线程1正在执行9
线程线程1正在执行10
线程线程2正在执行4
线程线程2正在执行5
线程线程2正在执行6
线程线程2正在执行7
线程线程2正在执行8
线程线程2正在执行9
线程线程2正在执行10

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值