线程调度
线程休眠
线程休眠通过调用sleep()方法实现,sleep(long millis)是java.lang.Thread类中定义的方法,单位为毫秒
class MyThread extends Thread{
@Override
public void run(){
for(int i = 0; i < 20; i++){
if(i == 5){
try{
sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("--------MyThread");
}
}
}
该线程在i==5时就会休眠1000毫秒,之后进入就绪状态,这是线程内部休眠操作,也可以在外部使用线程休眠操作
class MyThread extends Thread{
@Override
public void run(){
for(int i = 0; i < 20; i++){
System.out.println("--------------MyThread");
}
}
}
public calss Test{
public static void main(String[] args){
MyThread myThread = new MyThread();
try{
myThread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace(); }
}
myThread.start();
for(int i = 0; i < 20; i++){
System.out.println("--------------Test");
}
}
}
代码讲解:程序运行是MyThread子线程休眠1000毫秒之后再启动
如何让主线程休眠?
主线程不是我们手动实例化的线程对象,不能直接调用sleep()方法,这种情况下可以通过Thread类的静态方法currentThread来获取主线程对应的线程对象,然后调用sleep()
public class Test{
public static void main(String[] args){
for(int i = 0; i < 20; i++){
if(i == 6){
try{
Thread.currentThread().sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("------------------Test");
}
}
}
代码讲解:当i==6时,主线程就会进入休眠状态,1000毫秒后进入就绪状态
★无论通过哪种方式调用sleep(),都要注意处理异常,因为sleep()方法在定义时声明了可能会抛出的异常InterruptedException
线程合并
意思是指将指定的某个线程假如到当前线程中,合并为一个线程,由两个线程交替执行变成一个线程中的两个子线程顺序执行
jion()方法
class JoinRunnable implements Runnable{
@Override
public void run(){
for(int i = 0; i < 20; i++){
System.out.println(i+"---------------JoinRunnabel");
}
}
}
public class Test{
public static void main(String[] args){
JoinRunnable joinRunnable = new JoinRunnable();
Thread thread = new Thread(joinRunnable);
thread.start();
for(int i = 0 ; i < 200; i++){
if(i == 20){
try{
thread.join();
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println(i+"---------------------Test");
}
}
}
代码讲解:当主线程循环执行到i==20时,将子线程合并到主线程中,主线程进入阻塞状态,子线程执行完毕后,主线程再继续执行
jion(long millis)方法
- jion(long millis)表示调用此方法的线程执行millis毫秒之后,无论是否执行完毕,其他线程都可以和它来争夺CPU资源。
线程礼让
线程礼让是指在某个特定的时间点,让线程暂停抢占CPU资源的行为,讲CPU资源让给其他线程来使用。
- 线程礼让并不会一直等其他线程执行完毕后再来执行该线程,而是再特定的时间点礼让,过了这个时间点,该线程进入就绪状态争夺CPU资源。
- Java中的线程礼让,通过调用yield()方法完成
class YieldThread1 extends Thread{
@Override
public void run(){
for(int i = 0; i < 20; i++){
if(i == 8){
Thread.currentThread().yield();
}
System.out.println(i+"----------"+Thread.currentThread().getName());
}
}
}
class YieldThread2 extends Thread{
@Override
public void run(){
for(int i = 0; i < 30; i++){
System.out.println(i+"-----------"+Thread.currentThread().getName());
}
}
}
public class Test{
public static void main(String[] args){
YieldThread1 thread1 = new YieldThread1();
thread.setName("Thread-1");
YieldThread2 thread2 = new YieldThread2();
thread.setNmae("Thread-2");
thread1.start();
thread2.start();
}
}
代码讲解:setName()方法可以给线程自定义名称;thread1和thread2争夺CPU资源交替执行,当i==8时,thread1礼让进入祖代状态不争夺CPU资源,但过了这个时间点,继续争夺CPU资源
线程中断
- 线程中断有三种情况:
1.执行完毕之后自动停止
2.遇到错误会抛出异常并停止
3.情况需要,手动停止
- Java中实现线程中断机制的常用方法:
1.public void stop()(不推荐使用)
2.public void interrupt()
3.public boolean isInterrupt() - interrupt:是一个实例方法,调用时表示中断当前线程对象
- isInterrupt:用来获取当前线程对象的标志位。true表示清除了标志位,当前线程对象已经中断;false表示没有清除标志位了,当前线程对象没有中断。
对未启动的线程不存在中断
public class Test{
public static void main(String[] args){
Thread thread = new Thread();
//获取向前想成对象的状态
System.out.println(thread.getState());
thread.interrupt();
System.out.println(thread.isInterrupt());
}
}
讲解:NEW表示已经实例化线程对象,但并未启动,false表示当前线程并未中断。所以对未启动的线程不存在中断