zoukankan      html  css  js  c++  java
  • 线程常用方法介绍

    start():启动线程

    start方法启动一个新线程,start方法首先调用才能创建子线程,不能重复使用

    public synchronized void start() {
           group.add(this);
    
            boolean started = false;
            try {
                start0();
                started = true;
            } finally {
                try {
                    if (!started) {
                        group.threadStartFailed(this);
                    }
                } catch (Throwable ignore) {
                   
                }
            }
        }
    
        private native void start0();//调用native方法

    启动方法是需要底层OS来启动子线程,start是间接启动。

    native方法说明:

    JNI:Java native interface,java本地方法接口(JMM中存在本地方法栈),调度系统本身的提供的非Java代码(C/C++代码)。

    run():子线程的执行体

    整个子线程执行的业务逻辑都在run方法中;单独调用run方法,会在当前的线程中执行run()操作,和普通方法调用是一样的,不会启动子线程,run方法可以重复调用。Thread类中的run方法只是判断任务体Runable是否存在,未做其他业务,继承Thread是需要重写。

    start()和run()方法的区别:

    start()方法是用来启动子线程,start方法启动子线程后自动的来调用run方法。

    run()方法是子线程的业务执行体,不能直接调用run方法(通过调用run方法是不能操作子线程的),直接调用和普通方法一样。

     

    yield():线程让步

    方法在thread类中,是Thread类中静态方法,是用来暂停当前线程的执行,并且让步于其他相同优先级或更高优先级的线程先执行。

    方法特点:

    1、yield方法让步CPU的资源,让给谁由系统决定的,一般是让给相同优先级或者更高优先级的线程获得执行权,如果没有的话,会执行原来的线程

    2、yield让步:会让当前线程由“运行状态”进入到“就绪状态”,就绪状态的线程会按照优先级进行调度,等待CPU的调度。

    3、yield让步CPU资源后,线程不会释放锁。

     

    join():线程合并(插队)

    暂停当前线程执行,等待子线程的执行,也叫做线程合并,join方式是将并行执行的线程合并成串行执行,例:在线程ta中调用tb.join,会暂停ta的执行,先让tb执行完毕,ta才会执行。

    方法介绍:

    t.join() 允许t线程在当前线程之前执行,待t线程执行结束后当前线程再执行。

    t.join(long millis)(时间单位:毫秒)允许t线程在当前线程之前执行,且最长时间millis毫秒之后,当前线程才能执行。

    t.join(long millis, int nanos)与t.join(long)一样,只不过可以提供纳秒级的精度。

    方法特点:

    1、join方法是thread类中的方法,会抛出InterruptedException中断异常

    2、当前线程ta中tb.join,tb会执行,ta线程会进入WAITING或TIMED_WAITING状态。

    3、当前线程ta中tb.join,则ta线程会释放当前持有的锁join方法实现是通过wait/notify线程通信方式来实现的,wait方法的使用会释放锁。

    //一直等待子线程
    public final void join() throws InterruptedException {
            join(0);
    }
    //提供毫秒,纳秒级别的等待时间
    public final synchronized void join(long millis, int nanos) throws InterruptedException {
            if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
                millis++;
            }
             //纳秒的处理最终转换为毫秒处理
            join(millis);
        }
    //提供毫秒级别的等待时间
    public final synchronized void join(long millis)throws InterruptedException {
            if (millis == 0) {
                //millis=0,会一直判断子线程是否结束,否则会一直等待
                while (isAlive()) {
                    //线程等待
                    wait(0);
                }
            } else {
                //判断子线程是否结束且是否到达指定的毫秒数,否则会等待
                while (isAlive()) {
                    long delay = millis - now;
                    if (delay <= 0) {
                        break;
                    }
                    wait(delay);
                }
            }
        }

     

    interrupt():中断线程

    用来中断当前线程,终止处于“阻塞状态”的线程

    方法介绍:

    该方法在Thread类中,是一个普通方法,由对象调用该方法。

    boolean isInterrupted() 判断是否发送了中断操作, true:发生中断操作  false:未发生中断操作

     

    方法特点:

    1、如果当前线程是可中断的阻塞状态(join、sleep、wait)等方法会导致线程进入阻塞撞状态:WATING / TIMED_WAITING状态),在任意其他的线程中调用interruprt方法,那么会立即抛出InterruptedException来停止的阻塞状态

    2、如果当前线程是可运行状态。调用interruprt方法,线程还是会继续执行,直到发生了sleep、join、wait等方法的调用,才会在进入阻塞之后,随后立即抛出InterruptedException,跳出阻塞状态

     public void interrupt() {
            synchronized (blockerLock) {
                Interruptible b = blocker;
                if (b != null) {
                    interrupt0();           // Just to set the interrupt flag 注意这句
                    b.interrupt(this);
                    return;
                }
            }
            interrupt0();
        }
    
    private native void interrupt0(); //JNI方法,中断操作由系统来提供中断的方式

     

    sleep():线程休眠

    会让线程休眠,而且哪个线程调用,哪个线程休眠 ,TimeUtil.sleep(long),Thread.sleep、或当前的线程t.sleep,其结果都是当前的线程休眠。

    方法介绍:

    sleep(long millis)

    sleep(long millis, int nanos)

    都是提供休眠操作,时间单位粒度不同

    sleep 是Thread类提供的方法,会抛出InterruptedException异常

    方法特点:

    1、sleep休眠期间,会让出CPU使用权,但线程仍然持有锁。(抱着资源睡觉)

    2、sleep休眠时间到了之后,不会立即执行,而是线程由“阻塞状态”进入到“就绪状态”。

    public static native void sleep(long millis) throws InterruptedException  //JNI 
    
    public static void sleep(long millis, int nanos) throws InterruptedException {
            if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
                millis++;
            }
    
            sleep(millis);
        }

    deamon:守护线程

    方法介绍:

    setDaemon(boolean on) 设置线程为守护线程  true:表示是守护线程    false:非守护线程    默认false

    boolean isDaemon():判断当前线程是否是守护线程 true(守护线程)。

    Java中的线程主要有两种:用户线程和守护线程。

    守护线程和用户线程:

    用户线程:一般用户执行的用户级的线程。

    守护线程:也叫做后台线程,脱离于终端,用来服务于用户线程。 例如:GC是一个单独的线程处理,GC线程就是一个守护线程。

    守护线程的生命周期:

    依赖于用户线程,当有用户线程存在,守护线程就会存活,当没有用户线程存在,那守护线程也随之消亡,需要注意的是:Java虚拟机在“用户线程”都结束后会后退出。

     public final void setDaemon(boolean on) {
            checkAccess();
            if (isAlive()) {
                throw new IllegalThreadStateException();
            }
            daemon = on;
        }
        public final boolean isDaemon() {
            return daemon;
        }

    Priority:线程的优先级

    线程优先级,顾名思义:就是来指导线程的执行优先级的

    方法介绍:

    int getPriority()  获取优先级

    setPriority(int newPriority)  设置优先级

    方法特点:

    1、java线程的优先级并不绝对,它所控制的是执行的机会,也就是说,优先级高的线程执行的概率比较大,而优先级低的线程也并不是没有机会,只是执行的概率相对低一些。

    2、Java线程一共有10个优先级,分别为1-10,数值越大,表明优先级越高,一个普通的线程,其优先级为5(默认)线程的优先级具有继承性,如果一个线程B是在另一个线程A中创建的,则B叫做A的子线程,B的初始优先级与A保持一致。

     public final int getPriority() {
            return priority;
        }
    public final void setPriority(int newPriority) {
            ThreadGroup g;
            checkAccess();
            if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
                throw new IllegalArgumentException();
            }
            if((g = getThreadGroup()) != null) {
                if (newPriority > g.getMaxPriority()) {
                    newPriority = g.getMaxPriority();
                }
                setPriority0(priority = newPriority);
            }
        }
    
    private native void setPriority0(int newPriority); //JNI 
  • 相关阅读:
    【STM32F429的DSP教程】第8章 DSP定点数和浮点数(重要)
    【STM32F407的DSP教程】第8章 DSP定点数和浮点数(重要)
    【STM32H7的DSP教程】第7章 ARM DSP源码和库移植方法(IAR8)
    【STM32F429的DSP教程】第7章 ARM DSP源码和库移植方法(IAR8)
    【STM32F407的DSP教程】第7章 ARM DSP源码和库移植方法(IAR8)
    【STM32H7的DSP教程】第6章 ARM DSP源码和库移植方法(MDK5的AC5和AC6)
    【STM32F429的DSP教程】第6章 ARM DSP源码和库移植方法(MDK5的AC5和AC6)
    【STM32F407的DSP教程】第6章 ARM DSP源码和库移植方法(MDK5的AC5和AC6)
    【STM32H7的DSP教程】第5章 Matlab简易使用之常用编程语句
    【STM32F429的DSP教程】第5章 Matlab简易使用之常用编程语句
  • 原文地址:https://www.cnblogs.com/128-cdy/p/12482704.html
Copyright © 2011-2022 走看看