zoukankan      html  css  js  c++  java
  • Java中的线程状态转换和线程控制常用方法

    Java 中的线程状态转换:

      

    【注】:不是 start 之后就立刻开始执行, 只是就绪了(CPU 可能正在运行其他的线程).

    【注】:只有被 CPU 调度之后,线程才开始执行, 当 CPU 分配给你的时间片到了, 又回到就绪状态, 继续排队等候.

    线程控制的基本方法:

      isAlive(): 判断线程是否还活着, start 之后,终止之前都是活的;

      getPriority(): 获得线程的优先级数值;

      setPriority(): 设置线程的优先级数值(线程室友优先级别的);

        Thread.sleep(): 将当前线程睡眠指定毫秒数;

      join(): 调用某线程的该方法, 将当前线程与该线程合并, 也即等待该线程结束后, 再恢复当前线程的运行状态(比如在线程B中调用了线程A的 join() 方法,直到线程A执行完毕后,才会继续执行线程B);

      yield(): 当前线程让出 CPU, 进入就绪状态, 等待 CPU 的再次调度;

      wait(): 当前线程进入对象的 wait pool;

      notify()/notifyAll(): 唤醒对象的 wait pool 中的一个/所有的等待线程.

    1. sleep()方法:

      ① 可以调用 Thread 的静态方法:

        public static void sleep(long millis) throws InterruptedException:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响, 该线程不丢失任何监视器的所属权.

        InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除

      ② 由于是静态方法, sleep() 可以由类名直接调用.

        Thread.sleep(.....);

      Demo_1:

    import java.util.*;
    class TestThread {
    	public static void main(String[] args) {
    		MyThread thread = new MyThread();
    		thread.start();
    		try {                    // 在哪个线程中调用 Sleep,就让哪个线程睡眠
    			Thread.sleep(8000); // 主线程睡8秒后,打断子线程
    		} catch (InterruptedException e) {
    		}
    		thread.interrupt(); // 打断子线程
    	}
    }
    class MyThread extends Thread {
    	@Override
    	public void run() {
    		while(true){
    			System.out.println("=== "+ new Date()+" ===");
    			try {
    				sleep(1000); // 每隔一秒打印一次日期
    			} catch (InterruptedException e) {
    				return;
    			}
    		}
    	}	
    }
    

     运行结果:

    === Tue May 09 11:09:43 CST 2017 ===
    === Tue May 09 11:09:44 CST 2017 ===
    === Tue May 09 11:09:45 CST 2017 ===
    === Tue May 09 11:09:46 CST 2017 ===
    === Tue May 09 11:09:47 CST 2017 ===
    === Tue May 09 11:09:48 CST 2017 ===
    === Tue May 09 11:09:49 CST 2017 ===
    === Tue May 09 11:09:50 CST 2017 ===

    子线程每隔一秒打印系统日期, 主线程睡眠8秒后,打断子线程,子线程结束.

      Demo_2: 在本例中,采用一种简单、粗暴、好用的方法中断子线程

    import java.util.*;
    class TestThread {
    	public static void main(String[] args) {
    		MyThread thread = new MyThread();
    		thread.start();
    		try {                    // 在哪个线程中调用 Sleep,就让哪个线程睡眠
    			Thread.sleep(5000); // 主线程睡8秒后,打断子线程
    		} catch (InterruptedException e) {
    		}
    		thread.flag = false; // 打断子线程
    	}
    }
    class MyThread extends Thread {
    	boolean  flag = true;
    	@Override
    	public void run() {
    		while(flag){
    			System.out.println("=== "+ new Date()+" ===");
    			try {
    				sleep(1000); // 每隔一秒打印一次日期
    			} catch (InterruptedException e) {
    			}
    		}
    	}
    }
    

     运行结果:

    === Tue May 09 12:21:24 CST 2017 ===
    === Tue May 09 12:21:25 CST 2017 ===
    === Tue May 09 12:21:26 CST 2017 ===
    === Tue May 09 12:21:27 CST 2017 ===
    === Tue May 09 12:21:28 CST 2017 ===

    2. join()方法:

      合并某个线程, 相当于方法的调用

      Demo_3:

    class TestThread {
    	public static void main(String[] args) {
    		MyThread myThread = new MyThread("childThread");
    		myThread.start();
    		try {
    			myThread.join();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		for(int i = 1; i <= 4; i++){
    			System.out.println("I am the mainThread");
    		}
    	}
    }
    class MyThread extends Thread {
    	public MyThread(String name) {
    		super(name);
    	}
    	@Override
    	public void run() {
    		for(int i = 1; i <= 4; i++){
    			System.out.println("I am " + getName());
    			try {
    				sleep(1000);
    			} catch (InterruptedException e) {
    				return;
    			}
    		}
    	}
    }
    

     运行结果:

    I am childThread
    I am childThread
    I am childThread
    I am childThread
    I am the mainThread
    I am the mainThread
    I am the mainThread
    I am the mainThread

    等待线程结束后, 再恢复当前线程的运行.

    3. yield()方法:

      让出 CPU , 当前线程进入就绪状态队列等待, 给其他线程执行的机会(就让很小的一个时间片段).

    Demo_4:

    class TestThread {
    	public static void main(String[] args) {
    		MyThread my1 = new MyThread("t1");
    		MyThread my2 = new MyThread("t2");
    		my1.start();
    		my2.start();
    	}
    }
    class MyThread extends Thread {
    	public MyThread(String s) {
    		super(s);
    	}
    	@Override
    	public void run() {
    		for(int i = 1; i <= 100; i++){
    			System.out.println(getName()+":"+i);
    			if(i % 10 == 0) {
    				Thread.yield(); // 当前线程让出 CPU 一小会
    			}
    		}
    	}	
    }
    
  • 相关阅读:
    【Spring】IOC核心源码学习(二):容器初始化过程
    啃啃老菜:Spring IOC核心源码学习(一)
    快速理解Kafka分布式消息队列框架
    浅谈分布式缓存那些事儿
    JVM调优总结
    唉,程序员要是自学能力不行就等死吧!
    游戏开发入门
    JVM源码分析-Java运行
    Java阻塞队列的实现
    Java中堆内存和栈内存详解
  • 原文地址:https://www.cnblogs.com/bosongokay/p/6829100.html
Copyright © 2011-2022 走看看