zoukankan      html  css  js  c++  java
  • JavaSE——线程调度

    线程调度:

    按照特定机制为线程分配cpu的使用权。

    线程调度模型:

    分时调度

         所有线程轮流获得cpu的使用权,平均分配每个线程占用的cpu的时间片。

    抢占时调度(java虚拟机)

      可运行池中优先级高的线程有更大机会获得cpu使用权,如果可运行池中线程的优先级相同,则随机选择一个线程来使用cpu。

    线程的优先级:

    java中,优先级用整数 1-10 表示,Thread类有三个静态常量,

        MAX_PRIORITY: 10 表示最高优先级

      NORM_PRIORITY:5 表示默认优先级

      MIN_PRIORITY:1 表示最低优先级

    可以在编程过程中自己设定线程实例对象的优先级

    一个线程的优先级设置原则:

      线程创建时,子类继承父类的优先级。

      线程创建后,可通过调用setPriority()方法改变优先级。但是 ot.setpriority(Thread.MIN_PRIORITY) 要在start()之前

      线程的优先级是1-10之间的正整数,默认值是5。

      但优先级高的线程只是有更大可能获得cpu占用权但并不一定优先执行。

    后台线程:

      前台线程创建的线程实例对象为前台线程,如main线程;

      后台线程即为其他线程服务的线程,也称为守护线程,如JVM中的垃圾回收线程,负责回收其他线程不再使用的内存空间。

      设置线程为后台线程:

      mt.setDaemon(true)设置 mt 为后台线程。

      要在start()之前调用 setDaemon()否则会发生异常。

      若前台线程结束运行,则后台线程也结束。

    线程让步:

    yeild()方法

      当线程在运行过程中执行了Thread类的yeild()方法,此时如果有其他优先级等于或高于当前运行线程的线程处于就绪状态,则yeild()方法将把当前正在运行的线程放到可运行池中使其他线程运行,如果执行了yeild()方法,但没有符合条件的其他线程,则yeild()方法什么也不做。

       在java操作平台为抢占时调度模型,每一次循环相当于线程(此时运行池中所有线程)在一个时间片上运行,优先级均为默认值的两个线程随机占用cpu即运行先后顺序是随机的。此时,

    yeile()执行当 i为2时A线程运行后暂时让出cpu让步B线程运行。

     此时B线程的优先级低于A线程,虽然执行了yeild()方法,但yeild()方法不起任何作用。

    等待其他线程结束:

    join()方法

      当前运行的线程调用另一个线程的 join()方法,然后当前运行的线程转到堵塞状态,等到另一个线程运行结束(不管线程的优先级如何),它才会恢复到运行状态(转到就绪状态)。

    package jiaru;
    
    public class MyThread extends Thread {
        public  MyThread(String name){
            super(name);
        }
        
        public void run(){
            for(int i = 0;i<10;i++){
                System.out.println(Thread.currentThread().getName()+"----"+i);
                try {
                    sleep(200);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        }
    
    }
    package jiaru;
    
    public class Demo01 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		MyThread mt = new MyThread("b");
    		mt.start();
    		for(int i =0;i<5;i++){
    			System.out.println(Thread.currentThread().getName()+"---"+i);
    			try {
    				Thread.sleep(500);
    			} catch (InterruptedException e1) {
    				// TODO Auto-generated catch block
    				e1.printStackTrace();
    			}
    			if(i ==1){
    				try {
    					mt.join();
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		
    		}
    
    	}
    
    }
    

    运行结果:

          在主函数中,实例了一个mt线程,运行了该线程的start()方法后,该线程处于可运行状态,然后主函数继续向下运行,i = 0时,开始打印主线程,然后主线程此时有0.5秒的休眠时间,在此期间,b线程开始打印,由于b线程的休眠时间为0.2秒,所以每打印完一个main线程后在0.5秒内可以打印两个或者三个b线程。   i =1时,mt线程的join()方法被主函数调用,此时,main线程将转为堵塞状态让处于就绪状态的b 线程先运行,b运行结束后,主线程继续运行。

    如有不对之处还望指正,谢谢。

  • 相关阅读:
    android 回调的理解(结合接口)
    Android Bundle、Handler和Message类介绍
    Android: Intent实现活动之间的交互
    Condition实现一个生产者一个消费者
    condition实现通知部分线程
    Condition实现等待、通知
    ReentrantLock简单实现2
    ReentrantLock的简单使用
    线程通信-基于字符流管道
    线程通信-基于字节流管道
  • 原文地址:https://www.cnblogs.com/linlin0/p/6145670.html
Copyright © 2011-2022 走看看