Java 线程的基本控制

  • yield()
  • sleep()
  • join()


软件系统在实际运行过程中经常会有多个线程并发执行的情形发生,而且需要在特定时间或者条件下对哪一个线程的运行和停止进行控制,因此Java提供了几种方法对线程进行控制。

  • 相同优先级的线程d的让步(yield )
  • 线程的休眠(sleep)
  • 线程的挂起(suspend)和恢复(resume)
  • 线程的等待(wait)和通知(notify)

yield()

yield() 方法强制当前运行的线程让出虚拟CPU的使用权,使当前运行 的线程从运行状态过渡到可运行 状态(就绪状态),而不是进入阻塞状态

当时有两种情况调用yield方法不会使让出CPU而是继续执行(既yield不会生效)

  • 当前可运行状态中没有等待运行的线程,
  • 当前可运行状态中没有与调用yield线程相同优先级的线程(yield是相同优先级的线程间的让步)

注意! yield()方法是一个静态方法,可以使用类名或者在线程中直接调用yield方法。但是!!!!不能设置停止多长时间,只能靠线程调度器去控制何时进入下一次运行

ThreadA.java

public class ThreadA extends Thread {
    TestYield ty;
    int a = 0;
    public ThreadA(TestYield ty){
        this.ty = ty;
    }

    @Override
    public void run() {
        while (a++<50){
            ty.changData("ThreadA");//changData()使用了synchronized关键字,只有当changData()方法执行完之后,另一个线程才能执行changData()方法
            this.yield();
        }
    }
}

ThreadB.java

public class ThreadB extends Thread {
    TestYield ty;
    int a = 0;
    public ThreadB(TestYield ty){//线程的名字
        this.ty = ty;
    }

    @Override
    public void run() {
        while (a++<50){
            ty.changData("ThreadB");
        }
    }
}

TestYield.java

public class TestYield {
    private int data;
    public synchronized void changData(String name){
        data++;
        System.out.println("name="+name+"    data"+data);
    }
    public static void main(String[] args){
        TestYield ty = new TestYield();
        ThreadA ta = new ThreadA(ty);
        ThreadB tb = new ThreadB(ty);
        ta.start();
        tb.start();
    }
}

sleep()

当前运行的线程让出CPU,休眠一段时间并 进入阻塞状态,当休眠时候到的时候,该线程就会进入可运行状态等到调度器使其运行。

public static void sleep(long millisecnds) throws InterruptedException
//milliseconds 指定线程的睡眠时间(单位是毫秒)
public class SleepTest extends Thread {
    @Override
    public void run() {
        int i = 0;
        while(i++<10){
            System.out.println("i="+i);
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args){
        SleepTest s1 = new SleepTest();
        s1.start();
    }
}

java 进程监控 java进程控制_thread


java 进程监控 java进程控制_thread_02


每隔1秒就会输出一次

注意!!在这两种情况下,调用sleep依旧有效(依旧会让出CPU资源,睡眠一段时间并进入阻塞状态)



join()

连接方法可以使当前运行的线程处于等待状态(阻塞),直到 调用 join() 方法 的线程执行完毕

join方法的三种调用 格式

  • join() :如果当前的线程调用t.join() 方法,则当前线程将等待 t 线程结束后再继续执行
  • join(long millis ):如果当前线程调用t.join(millis )方法,则当前线程将等待 t 线程结束或最多等待,millis毫秒后再继续执行。(既如果 A线程等待millis毫秒之后: 如果 t 线程执行完毕,那么执行A线程继续执行;如果 t 线程依旧没有执行完毕,那么 t 进入就绪状态,让出CPU资源,让A执行)
  • join(long millis ,int nanos):如果当前线程调用t.join(millis )方法,则当前线程将等待 t 线程结束或最多等待,millis毫秒+nanos纳秒 后再继续执行。
class ThreadB extends Thread{
     @Override
     public void run() {
         System.out.println("running the ThreadB");
         try {
             sleep(10000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         System.out.println("end ThreadB");
     }
 }
class ThreadA extends Thread{
     ThreadB tb;
     public ThreadA(ThreadB tb){
         this.tb = tb;
     }

     @Override
     public void run() {
         System.out.println("running the ThreadA");
         try {
             tb.join();//join使当前的线程处于等待状态(阻塞),直到调用join()方法的线程执行完毕。
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         System.out.println("end ThreadA");
     }
 }
public class TestJoin {
    public static void main(String[] args){
        ThreadB tb = new ThreadB();
        ThreadA ta = new ThreadA(tb);
        ta.start();
        tb.start();
    }
}

java 进程监控 java进程控制_多线程_03


java 进程监控 java进程控制_thread_04