Java线程的调度(线程的优先级、线程睡眠、线程让步、线程插队)

线程的优先级 :
Java语言中线程有优先级,优先级高的线程会获得较多的运行机会。 当程序中有多个线程存在的时候,线程和线程之间的关系并非是平等的。
Java语言中线程的优先级用整数表示,取值范围是1~10,Thread类由以下三个静态常量表示线程的优先级。
(1)static int MAX_PRIORITY
线程可以具有的最高优先级,取值为10。
(2)static int MIN_PRIORITY
线程可以具有的最低优先级,取值为1。
(3)static int NORM_PRIORITY
分配给线程的默认优先级,取值为5。
Thread类的方法setPriority()和getPriority()分别用来设置和获取线程的优先级。

package thread;

public class _5_线程的优先级 {
public static void main(String[] args) {
	MySleeps ms = new MySleeps();
	Thread t1 = new Thread(ms,"a");
	Thread t2 = new Thread(ms,"b");
	Thread t3 = new Thread(ms,"c");
	System.out.println(t1.getPriority());//默认的优先级为普通的优先级——5
	t1.setPriority(Thread.MAX_PRIORITY);//最大——10
	t3.setPriority(Thread.MIN_PRIORITY);//最小——1
	t1.start();
	t2.start();
	t3.start();
}
}

class MySleeps implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0 ; i<40 ; i++) {
			System.out.println(Thread.currentThread().getName()+"   "+i);
		}
	}
	
}

在这里插入图片描述
在这里插入图片描述

由上图的运行结果可以知道,优先级高的可以获得更多的机会优先执行。
Java中虽然提供了10个线程优先级,但是这需要电脑操作系统的支持,不同操作系统对优先级的支持是不一样的,不能很好的和Java中线程优先级一一对应。
因此,在设计多线程应用程序的时候,其功能的实现一定不能依赖于线程的优先级,而只能将线程的优先级作为一种提高程序效率的手段。

线程睡眠:
方法Thread.sleep(long millis),使线程转到阻塞状态。millis参数设定睡眠的时间,以ms为单位。当睡眠结束后,就转为就绪(Runnable)状态。
当睡眠时间到期,则返回到可运行状态。
睡眠的位置:为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内。这样才能保证该线程执行过程中会睡眠。
sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。

package thread;

public class _6_Sleep线程睡眠 {
public static void main(String[] args) {
	MySleep ms = new MySleep();
	Thread t1 = new Thread(ms,"a");
	Thread t2 = new Thread(ms,"b");
	Thread t3 = new Thread(ms,"c");
	t1.start();
	t2.start();
	t3.start();
}
}

class MySleep implements Runnable{

	@Override
	
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0 ; i<40 ; i++) {
			System.out.println(Thread.currentThread().getName()+"   "+i);
			if(i==6)
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}


在这里插入图片描述

在结果中可以看出,当i==6的时候,该线程就会进入短暂的睡眠,而进行下一个线程的运行(也有可能进入睡眠后又醒了继续抢夺cpu,继续进行该线程,就是几率有点小)

线程让步:

方法Thread.yield(),暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。
package thread;

public class _7_yield线程让步 {
		public static void main(String[] args) {
			//创建两个线程
			Thread t1 = new YieldThread("one");
			Thread t2 = new YieldThread("two");
			//开启两个线程
			t1.start();
			t2.start();
		}
}

class YieldThread extends Thread{
	public YieldThread(String name) {
		super(name);
	}
	public void run() {
		for(int i = 0 ; i < 5 ; i++) {
			System.out.println(Thread.currentThread().getName()+"   "+i);
			if(i==2) {
				System.out.println("线程让步");
				Thread.yield();
			}
		}
	}
}

在这里插入图片描述

该方法与sleep(参数)方法类似,都可以让当前正在运行的线程暂停,区别在于yield()方法不会阻塞该线程,它只是将线程转换为就绪状态,让系统的调度器重新调度一次。当某个线程调用yield()方法后,与当前线程优先级相同或者更高的线程可以获得执行的机会。
由于Java虚拟机默认采用抢占式调度模式,所有线程都会再次抢占CPU资源抢夺权,所以执行线程让步后不能保证立即执行其他线程。

线程插队(加入):
方法join(),等待这个线程执行结束。在当前线程中调用另一个线程的方法join(),则当前线程转入阻塞状态,直到另一个线程运行结束,当前线程再由阻塞转为就绪状态。

package thread;

public class _8_join线程插队 {
		public static void main(String[] args) {
			MyJoin mj = new MyJoin();
			Thread t = new Thread(mj,"one");
			t.start();
			for(int i = 0 ; i <40;i++) {
				System.out.println("main    "+i);
				if(i==20)//加入的线程先运行完再运行主线程
					try {
						t.join();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			}
		}
}

class MyJoin implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i = 0 ; i <40;i++) {
		System.out.println(Thread.currentThread().getName()+"  "+i);
		}
	}
	
}

在这里插入图片描述
可以看出,当main=20的时候,进行了插队,当one线程全部结束的时候才继续进行main线程

线程类的常用方法:

  1. 类方法
    在这里插入图片描述
  2. 实例方法

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱睡觉的小馨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值