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

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

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

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值