精华内容
下载资源
问答
  • Java多线程常用方法

    2021-02-26 14:40:39
    start()与run()start() 启动线程并执行相应的run()方法run() 子线程要执行的代码放入run()方法getName()和setName()getName() 获取此线程的名字setName() 设置此线程的名字isAlive()是判断当前线程是否处于活动状态...

    start()与run()

    start() 启动线程并执行相应的run()方法

    run() 子线程要执行的代码放入run()方法

    getName()和setName()

    getName() 获取此线程的名字

    setName() 设置此线程的名字

    isAlive()

    是判断当前线程是否处于活动状态。活动状态就是已经启动尚未终止。

    currentThread()

    返回代码段正在被哪个线程调用

    sleep()

    主要的作用是让当前线程停止执行,把cpu让给其他线程执行,但不会释放对象锁和监控的状态,到了指定时间后线程又会自动恢复运行状态

    注意:线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行

    yield()

    中文意思:放弃,屈服

    一个线程调用yield()意味着告诉虚拟机自己非常乐于助人,可以把自己的位置让给其他线程(这只是暗示,并不表绝对)。但得注意,让出cpu并不代表当前线程不执行了。当前线程让出cpu后,还会进行cpu资源的争夺,但是能不能再次分配到,就不一定了

    getPriority()和setPriority(int newPriority)

    这两个方法是用于获取当前和设置线程的优先级。优先级高的线程得到的cpu多。也就是说,两个等待的线程,优先级高的线程容易被cpu执行。

    默认情况下,线程的优先级是5。线程的优先级分为1~10等级。

    getId()

    取得线程唯一标识

    yield()

    yield() 暂停当前方法,释放自己拥有的CPU,线程进入就绪状态。

    join()

    所属线程对象x正常执行run,当前线程z无限等待直到执行完。常用于需要子线程的执行结果

    interrupted()

    interrupted()是静态方法:内部实现是调用的当前线程的isInterrupted(),并且会重置当前线程的中断状态

    isInterrupted()是实例方法,是调用该方法的对象所表示的那个线程的isInterrupted(),不会重置当前线程的中断状态

    它们的作用是判断线程是否是停止状态

    isDaeMon、setDaemon(boolean on)

    java线程有两种,一种是用户线程,一种是守护线程。守护线程是一个特殊的线程,任何一个守护线程都是jvm中所有非守护线程的保姆。当进程中不存在非守护线程时,守护线程会自动销毁。典型的守护线程就是垃圾回收线程。

    第一个是判断线程是不是守护线程,第二个是设置线程为守护线程,必须在线程start之前setDaemon(true)。

    stop()

    强制停止,已废弃

    可能释放锁导致数据不对。

    可能导致清理工作做不好。

    suspend和resume

    暂停和恢复

    会造成独占(永远的暂停)(方法)

    造成不同步

    展开全文
  • http://blog.csdn.net/zuoluoboy/article/details/4034935#常用的线程方法:sleep(), join(),yield...尽管线程对象的常用方法可以通过API文档来了解,但是有很方法仅仅从API说明是无法详细了解的。本来打算用一节的...

    http://blog.csdn.net/zuoluoboy/article/details/4034935#

    常用的线程方法:sleep(),  join(),

    yield(),  wait(), notify(),

    notifyAll().

    注意实现Runnable接口类的对象实例化的方式.

    尽管线程对象的常用方法可以通过API文档来了解,但是有很多方法仅仅从API说明是无法详细了解的。

    本来打算用一节的篇幅来把线程方法中一些重要的知识说完,但这样下来估计要很常的篇幅,可能要用好几节才能说把和线程方法相关的一些重要的知识说完。

    首先我们接基础篇(二)来说明start()方法。

    一个线程对象生成后,如果要产生一个执行的线程,就一定要调用它的start()方法.在介绍这个方法时不得不同时说明run方法.其实线程对

    象的run方法完全是一个接口回调方法,它是你这个线程对象要完成的具体逻辑.简单说你要做什么就你在run中完成,而如何做,什么时候做就不需要你控制

    了,你只要调用start()方法,JVM就会管理这个线程对象让它产生一个线程并注册到线程处理系统中。

    从表面上看,start()方法调用了run()方法,事实上,start()方法并没有直接调用run方法.在JDK1.5以前

    start()方法是本地方法,它如何最终调用run方法已经不是JAVA程序员所能了解的.而在JDK1.5中,原来的那个本地start()方法被

    start0()代替,另个一个纯JAVA的start()中调用本地方法start0(),而在start()方法中做了一个验证,就是对一个全局变量

    (对象变量)started做检验,如果为true,则start()抛出异常,不会调用本地方法start0(),否则,先将该变量设有true,然后

    调用start0()。

    从中我们可以看到这个为了控制一个线程对象只能运行成功一次start()方法.这是因为线程的运行要获取当前环境,包括安全,父线程的权限,

    优先级等条件,如果一个线程对象可以运行多次,那么定义一个static

    的线程在一个环境中获取相应权限和优先级,运行完成后它在另一个环境中利用原来的权限和优先级等属性在当前环境中运行,这样就造成无法预知的结果.简单说

    来,让一个线程对象只能成功运行一次,是基于对线程管理的需要。

    start()方法最本质的功能是从CPU中申请另一个线程空间来执行

    run()方法中的代码,它和当前的线程是两条线,在相对独立的线程空间运行,也就是说,如果你直接调用线程对象的run()方法,当然也会执行,但那是

    在当前线程中执行,run()方法执行完成后继续执行下面的代码.而调用start()方法后,run()方法的代码会和当前线程并发(单CPU)或并行

    (多CPU)执行。

    所以请记住一句话[调用线程对象的run方法不会产生一个新的线程,虽然可以达到相同的执行结果,但执行过程和执行效率不同。

    [线程的interrupt()方法,interrupted()和isInterrupted()]

    这三个方法是关系非常密切而且又比较复杂的,虽然它们各自的功能很清楚,但它们之间的关系有大多数人不是真正的了解。

    先说interrupt()方法,它是实例方法,而它也是最奇怪的方法,在java语言中,线程最初被设计为"隐晦难懂"的东西,直到现在它的

    语义不没有象它的名字那样准确。大多数人以为,一个线程象调用了interrupt()方法,那它对应的线程就应该被中断而抛出异常,事实中,当一个线程

    对象调用interrupt()方法,它对应的线程并没有被中断,只是改变了它的中断状态。

    使当前线程的状态变以中断状态,如果没有其它影响,线程还会自己继续执行。

    只有当线程执行到sleep,wait,join等方法时,或者自己检查中断状态而抛出异常的情况下,线程才会抛出异常。

    如果线程对象调用interrupt()后它对应的线程就立即中断,那么interrupted()方法就不可能执行。

    因为interrupted()方法是一个static方法,就是说只能在当前线程上调用,而如果一个线程interrupt()后它已经中断了,那它又如何让自己interrupted()?

    正因为一个线程调用interrupt()后只是改变了中断状态,它可以继续执行下去,在没有调用sleep,wait,join等法或自己抛

    出异常之前,它就可以调用interrupted()来清除中断状态(还会原状)interrupted()方法会检查当前线程的中断状态,如果为

    "被中断状态"则改变当前线程为"非中断状态"并返回true,如果为"非中断状态"则返回false,它不仅检查当前线程是否为中断状态,而且在保证当

    前线程回来非中断状态,所以它叫"interrupted",是说中断的状态已经结束(到非中断状态了)isInterrupted()方法则仅仅检查线

    程对象对应的线程是否是中断状态,并不改变它的状态。

    目前大家只能先记住这三个方法的功能,只有真正深入到多线程编程实践中,才会体会到它们为什么是对象方法,为什么是类方法。

    线程到底什么时候才被中断抛出InterruptedException异常,我们将在提高篇中详细讨论。

    [sleep(),join(),yield()方法]

    在现在的环节中,我只能先说明这些方法的作用和调用原则,至于为什么,在基础篇中无法深入,只能在提高篇中详细说明。

    sleep()方法中是类方法,也就是对当前线程而言的,程序员不能指定某个线程去sleep,只能是当前线程执行到sleep()方法时,睡

    眠指定的时间(让其它线程运行).事实上也只能是类方法,在当前线程上调用.试想如果你调用一个线程对象的sleep()方法,那么这个对象对应的线程如

    果不是正在运行,它如何sleep()?所以只有当前线程,因为它正在执行,你才能保证它可以调用sleep()方法。

    原则:[在同步方法中尽量不要调用线程的sleep()方法],或者简单说,对于一般水平的程序员你基本不应该调用sleep()方法。

    join()方法,Thread的非静态方法join()让一个线程B“加入”到另外一个线程A的尾部。在A执行完毕之前,B不能工作,也就是在线程B中调用线程A对象的join()方法时,B必须等到A执行完成后才能执行.

    原则:[join是测试其它工作状态的唯一正确方法],我见过很多人,甚至有的是博士生,在处理一项工作时如果另一项工作没有完成,说让当前工

    作线程sleep(x),我问他,你这个x是如何指定的,你怎么知道是100毫秒而不是99毫秒或是101毫秒?其实这就是OnXXX事件的实质,我们不

    是要等多长时间才去做什么事,而是当等待的工作正好完成的时候去做。

    yield()方法也是类方法,只在当前线程上调用,理由同上。当一个线程抢到执行权后,执行到yield()方法后,就会放弃执行权,放弃本次分配到的时间片,其他线程就可以拿到执行权

    了。原则:[不是非常必要的情况下,没有理

    由调用它].调用这个方法不会提高任何效率,只是降低了CPU的总周期上面介绍的线程一些方法,基于(基础篇)而言只能简单提及.以后具体应用中我会结合

    实例详细论述。

    wait(),notify()(这两个不是静态方法)必须要与synchronized(Obj)一起使用,也就是wait,与notify只能在取得对象锁的时候才能调用。从语法角度来说就是wait(),

    notify必须在synchronized(Obj){...}语句块内。从功能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。

    Thread.sleep()与wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。

    notify()方法表示,当前的线程已经放弃对资源的占有,通知等待的线程来获得对资源的占有权,但是只有一个线程能够从wait状态中恢复,

    然后继续运行wait()后面的语句;

    notifyAll()方法表示,当前的线程已经放弃对资源的占有,通知所有的等待线程从wait()方法后的语句开始运行。

    [wait(),notify()/notityAll()方法是普通对象的方法(Object超类中实现),而不是线程对象的方法]

    [wait(),notify()/notityAll()方法只能在同步方法中调用]

    展开全文
  • 目录常用API 总结概览静态 -Yield 方法实例方法-join中断线程获取中断标志位interrupt 和 isInterrupted()线程状态 Thread.State线程的优先级守护线程 常用API 总结概览 方法 描述 静态方法 作用在当前代码...

    常用API 总结概览

    方法描述
    静态方法作用在当前代码所在的线程
    static void sleep(long millis )当前线程休眠 给定的时间,时间单位是毫秒
    static Thread currentThred获取代码行所在的当前线程
    static void yield()暂停当前正在执行的线程对象,并执行其他线程 当前线程让步,从运行态转变为就绪态
    static int activeCount获取当前线程组中,还存活的线程数量
    static boolean interrupted获取当前线程的中断标志位,并重置
    方法描述
    实例方法作用在调用的线程对象
    void run()定义线程的任务,线程真正运行时的方法
    void start()启动线程 申请系统调度运行线程
    String getName()获取线程名称
    void interrupt()中断线程
    boolean isInterrupted()获取线程中断标志位 不重置标志位
    void join()等待该线程终止-无条件等待,有参数就是限时等待
    void setDaemon(boolean on)设置守护线程
    boolean isAlive()测试线程是否处于活动状态
    int getPriority获取线程优先级 返回的是0-10的数值
    void setPriority(int newPriority)更改线程优先级
    Thread.State getState获取线程状态

    静态 -Yield 方法

    当前线程让步,从运行态转变为就绪态,让当前正在执行的线程暂停,但不阻塞。礼让不一定成功,看cpu心情。

    public static void main(String[] args) throws InterruptedException {
            Thread [] threads = new Thread[20];
            for(int i = 0; i <20 ;i++) {
                final int n = i; // 内部类使用外部的变量该变量必须是final 修饰 和JVM 有关
                threads[i] = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(n);
                    }
                });
            }
            for(Thread t : threads) {
                t.start();//同时将20个线程启动
            }
    
             //但实际中不会这么用
            //静态方法:作用是在当前线程 -- 当前代码所在的线程是main -- 只能使用debug
            while (Thread.activeCount() > 1) {  //获取当前线程的活跃数量 如果数量大于1 就让当前线程--即main 线程让步
                Thread.yield(); // 让当前线程mian让步变为就绪态 : 确保其他线程先执行
            }
            System.out.println("ok");
        }
    

    注意:小tips
    Thread.activeCount() > 1 采用这样的写法的时候,只能用debug的方法启动,这样才能确保当其他线程运行完毕后,打印main 线程的ok。
    因为idea 会启动其他线程(这里是指出来main 和 20个线程的其他线程),如果直接run 运行代码,会在这里的进入死循环,后面的ok 不会打印。如果想要用run 运行,将条件改成 Thread.activeCount() > 2 即可。

    礼让不一定成功

    public class TestYield {
    
        public static void main(String[] args) {
            MyYield myYield = new MyYield();
    
            new Thread(myYield,"a").start();
            new Thread(myYield,"b").start();
        }
    }
    class MyYield implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"线程开始执行");
            Thread.yield();//让步
            System.out.println(Thread.currentThread().getName()+"线程停止执行");
        }
    }
    

    运行结果1 – 让步不成功:
    b线程开始执行
    b线程停止执行
    a线程开始执行
    a线程停止执行

    运行结果2 – 让步成功:
    a线程开始执行
    b线程开始执行
    b线程停止执行
    a线程停止执行
    让步一次成功 :a 线程开始执行的时候,执行到 run 方法里面的 Thread.yield(); 表示当前代码行所在的线程让步即a让步,b执行。a 给b让步,b在执行让步的时候,没让步成功。

    运行结果3 – 让步成功:
    b线程开始执行
    a线程开始执行
    b线程停止执行
    a线程停止执行
    也是让步执行成功了,只是和上面的区别是 让步两次都成功了,b 让了 a ,结果a 又让了b。

    实例方法-join

    上面的yield 方法表示当前线程让步,但实际中使用的不多而且还不可靠,还是主要使用实例 join 方法。
    t.join 对 t 线程没有什么影响,影响的是当前线程。join 方法会让当前线程处于waiting 状态(也就可以理解为阻塞)t 线程join(参加加入进来!)比如当我有main 线程和 t 线程的时候,我在main 线程里面调用t.join () 表示等待t 线程执行完毕之后,main线程再执行。

    使用它通常对应很多现实世界的事情,就是我要等待其他线程办完事,才能继续做事情
    很多业务在执行(main)的时候,开启其他线程执行工作量大或者代码可能会出现阻塞的提升效率,但是我的main 线程需要其他线程运行完后的数据。

    无参数
    下面两个代码的区别

    for(Thread t : threads) {
                t.start();
                t.join(); 
               //这个表示先启动一个线程,启动后main 等待它执行完 
               //在启动下一个 main 再等待,这样的线程执行是顺序的
               //打印的结果是顺序的
            }
    

    把启动和join 分开写

    for(Thread t : threads) {
                t.start();
    }
     for(Thread t: threads) { // 同时执行20个线程,让main 等待20个线程执行完
                t.join(); 
                // 这个表示的是同时启动之后,
                //如果一个线程还没有执行就让main 等待
                // 如果一个线程在这之前已经执行完了,就告诉main 否则我会一直等待
            }
    

    这样分开启动,分别启动join 方法,可能会涉及到一个线程已经运行完了。当一个线程已经运行完了以后,再去调用它的 join 方法,没有什么影响。

    有参数
    当前线程main 是限时等待,直到t线程执行完毕,或者给定的时间已经到了

    public static void main(String[] args) throws InterruptedException {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(3000);
                        System.out.println("t");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
            t.join(); //无条件等待
             t.join(1000); // 当前线程main 是限时等待,直到t线程执行完毕,或者给定的时间已经到了
            // 具体的时间看两个时间哪一个先到,到了之后先往后在
            // 先等 1 s 打印main 然后等3 s 打印t
            t.join(4000); // 先等待3 s 打印t 然后执行main
            //系统调度t由就绪态转变为运行态 加上 t 的运行时间
            System.out.println("main");
        }
    

    归纳总结
    无参数的join :当前线程无条件等待,直到调用线程执行完
    有参数的join :当前线程有条件等待,直到调用线程执行完或者时间片(参数里面的时间)用完 其实等待时间就是线程执行时间和参数等待时间这两个时间里面最小的那个,就会往下执行。

    中断线程

    中断线程会用到三个API :

    • 静态方法:static boolean interrupted()
    • 实例方法:void interrupt()
    • 实例方法:boolean isInterrupted()

    在这里插入图片描述

    获取中断标志位

    • 静态方法 interrupted()
      Thread.interrupted() 判断当前线程的中断标志被设置,清除中断标志位(重置)
    • 实例方法 Thread.currentThread().isInterrupted()
      判断指定线程的中断标志被设置,不清除中断标志

    其实我们可以做到自己写一个静态变量flag 然后控制静态变量的值,使得线程终止,但这样做会产生一个问题就是,如果我告诉线程你需要终止的时候,线程处于阻塞状态,那么这个线程是终止不了的。但是采用官方的API 可以解决当线程处于阻塞状态无法终止的问题。

    为什么自己写标志位无法中断线程的代码说明:

    public class StopThreadTest {
        private  static volatile boolean STOP = false; // volatile关键字后续会讲解
        public static void main(String[] args) throws InterruptedException {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    // ..执行任务,执行时间可能比较长
                    try {
                        for(int i = 0 ; i <10000 && !STOP;i++) {
                            System.out.println(i);
                            //模拟终端线程
                            Thread.sleep(1000);  // 阻塞时间比较短可以解决
                            // 通过标志位自行实现其实就是无法解决因为线程处于阻塞状态而终止线程
                            //这里只是用sleep 来模拟,由于sleep 有时间限制
                            Thread.sleep(10000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
            System.out.println("t start");
            Thread.sleep(500);
            //让t 线程中断掉 停止
            STOP = true;
            System.out.println("t stop");
        }
    }
    

    其实你让线程休眠时间长一点,只是时间长,最后还是会结束,这里只是想用休眠模拟线程阻塞,但真实的线程阻塞有很多。 如果我今天是等待输入的io阻塞的话,那我就一直阻塞,线程一直不终止,那么通过自己设置中断标志位就无法实现。

    interrupt 和 isInterrupted()

    上面说自己写中断标志位,无法解决线程处于阻塞态的时候让线程终止,而interrupt即使线程处于阻塞态,也可以终止线程–是以抛出异常的方式终止。但线程是否停止运行,取决于代码是怎么写的。
    isInterrupted() 是获取线程的中断标志位。
    注意观察 try catch 的位置

    代码说明
    try-catch 包裹整个for循环

    public static void main(String[] args) throws InterruptedException {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    //中断以后,停止程序代码演示
                    try {
                        for(int i = 0 ; i <10000 &&  !Thread.currentThread().isInterrupted() ;i++) {
                            System.out.println(i);
                            //模拟终端线程
                            Thread.sleep(100000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start(); // 线程启动中断标志位=false
            System.out.println("t start");
            //模拟t执行五秒,还没有停下来,要中断t
            Thread.sleep(5000);
            //让t 线程中断掉 停止
            // (设置t 线程的中断标志位为true),告诉了以后由t 的代码自行决定是否中断
            //如果t线程处于阻塞状态会抛出InterruptedException , 并且重置中断标志(这就是继续运行的原因)
            t.interrupt();
            System.out.println("t stop");
        }
    

    中断之后,线程结束
    在这里插入图片描述

    try catch 只包裹 sleep
    更改run 方法try catch 的位置

    //中断以后,继续执行--try catch 的位置和上面的不一样
                    for (int i = 0; i < 10000 && !Thread.currentThread().isInterrupted(); i++) {
                        System.out.println(i);
                        //模拟终端线程
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    

    抛出异常以后,继续执行代码
    在这里插入图片描述

    看到这里,有没有些许疑惑?的确,interrupt 是可以将处于阻塞态的代码通过抛出异常的方式终止,但是这还要看我的代码是怎么写的。
    异常抛出,我会继续for 循环,一个是因为try catch 只包裹 sleep,还有一个原因是会重置中断标志。(刚开始告诉你中断标志位设置位true 之后,interrupt 会重置它为false的!)

    t.interrupt() 的作用就是告诉t 线程要中断了(设置t 线程的中断标志位为true),如果t线程处于阻塞状态会抛出InterruptedException , 并且重置中断标志,告诉了以后由 t 的代码自行决定是否中断。(上面演示的就是try -catch位置不同,线程会有不马上中断的可能,当然任务执行完就中断了,只是没有在我通知它的时候及时中断 )

    线程状态及转换

    线程的状态是一个枚举类型Thread.State

            for(Thread.State state : Thread.State.values()){
                System.out.println(state);
            }
    

    六大状态
    在这里插入图片描述
    NEW (新建)
    RUNNABLE(包含就绪ready 和 运行中 Running 两种) 可运行状态
    BLOCKED(阻塞)
    WAITING(等待)
    TIMED_WAITING(限时等待)–有时间限制
    TERMINATED(终止)
    阻塞、等待、限时等待这三个都是对应着进程的阻塞。

    线程中断或者结束后,一旦进入死亡状态就不能再次启动,也就是说一个线程只能启动一次。

    Thread.getState 方法

    public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(()->{
                for (int i = 0; i < 5; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("//");
            });
    
    
            //观察状态
            Thread.State state = thread.getState();//alt+enter 可以创建变量
            System.out.println(state);//new
            
            //观察启动后
            thread.start();
            System.out.println(thread.getState());//RUNNABLE
    
            while (thread.getState() != Thread.State.TERMINATED) { // 只要线程不终止就一直输出下去
                Thread.sleep(100);
                state = thread.getState(); // 更新线程状态
                System.out.println(state);  //TIMED_WAITING
            }
    
            //线程中断或者结束后,一旦进入死亡状态就不能再次启动
            // 一个线程不能启动该两次,死亡以后就不能再启动了
            thread.start();
    
        }
    

    线程的优先级

    priority 线程的优先级用数字表示,范围从1~10

    public final static int MIN_PRIORITY = 1;
    public final static int NORM_PRIORITY = 5;(默认优先级)
    public final static int MAX_PRIORITY = 10;

    使用getPriority()方法来获取优先级
    setPriority(int xxx)来改变优先级。
    要先设置优先级再启动
    (启动之后在设置没有意义啦)

    优先级高不一定会先执行,优先级低只是意味着获得调度的概率低,并不是优先级低就不会被调度了。

    既然优先级高的不一定会先执行,那我设置优先级意义是什么?
    这个只是一个给系统的建议。但这个优先级不可靠,系统不一定能满足。
    就好像你给别人建议,别人听不听那你可管不着。它采纳建议是最好的,不采纳你也没办法。但你还是会一直建议。

    守护线程

    线程分为用户线程和守护线程
    虚拟机必须确保用户线程执行完毕(main),但不用等待守护线程执行完毕(gc)。守护线程例如:后台记录操作日志、监控内存、垃圾回收(gc)等等。
    设置守护线程的方法是 setDaemon

    public final void setDaemon(boolean on)
    设置布尔值为 true,标志着这个线程为守护线程 ,默认false 用户线程
    用户线程执行完毕后,守护线程就会被结束(但不是马上就被结束,需要时间)
    虚拟机不用等待守护线程运行完毕

    展开全文
  • Java中多线程常用方法

    2021-03-17 21:59:29
    文章目录一、多线程常用方法1.start方法2.sleep方法3.yield方法4.join方法5.wait,notify,notifyAll方法6.线程中断方法 一、多线程常用方法 1.start方法 start():启动一个线程,将线程添加到一个线程组中,同时线程...

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

    一、多线程常用方法

    1.start方法

    start():启动一个线程,将线程添加到一个线程组中,同时线程状态会从new状态转化到runnable状态,线程在获取到cpu资源后进入running状态执行run()

    public class main {
        public static void main(String[] args) {
            Mythread mythread = new Mythread();
            mythread.start();
        }
    }
    
    class Mythread extends Thread{
        @Override
        public void run(){
            System.out.println("testStart");
        }
        }
    

    运行结果:

    testStart
    
    Process finished with exit code 0
    
    

    2.sleep方法

    sleep():使得线程进入睡眠状态,暂停执行。
    sleep是一个静态方法,其中存在两个重载函数
    ●public static native void sleep(long millis)
    ●public static void sleep(long millis, int nanos)
    **sleep不会放弃monitor lock的所有权(与wait()的不同)
    <由于sleep传入参数只有上述两种因此在转化平常时间时需要计算因此常用枚举TimeUnit来转化带小时分钟之类的时间,如下休眠三小时>

    
    import java.util.concurrent.TimeUnit;
    
    public class TestDemo1 {
        public static void main(String[] args) {
            Thread thread = new Thread(){
                @Override
                public void run(){
                    while(true){
                        try {
                            TimeUnit.HOURS.sleep(3);
                            System.out.println("休眠已完成");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            thread.start();
        }
    }
    
    

    3.yield方法

    yield方法:表示提醒cpu调度器,我愿意放弃当前的cpu资源(属于启发式方法),如果cpu资源不紧张的情况下会忽略这种提示。
    yield和sleep的区别
    1.jdk1.5之前。yield调用sleep
    2.sleep是的当前线程休眠后不会占用cpu资源;yield只是对于cpu调度器的一个提示
    3.sleep会使线程进入短暂的阻塞,yield会使线程从running状态转化为runnable状态
    4.sleep会捕获到中断异常,yield则不会捕获到中断异常


    4.join方法

    join():在线程B中join线程A会使得线程B进入等待,直到线程A结束生命周期或达到等待时间,在这期间线程B处于等待状态
    按顺序让ABC三个线程打印1-》3
    不加join方法时

    public class TestDemo2 {
    
        public static void main(String[] args) {
           MyThread A = new MyThread("线程A",null);
           MyThread B = new MyThread("线程B",A);
           MyThread C = new MyThread("线程C",B);
            A.start();
            B.start();
            C.start();
        }
      }
         class MyThread extends Thread{
            private String name;
            private Thread thread;
    
            public MyThread(String name,Thread thread) {
                this.name = name;
                this.thread = thread;
            }
    
            @Override
            public void run(){
    
                for (int i = 1;i <= 3;i++){
                    System.out.println(name +":" + i);
                }
            }
    
        }
    
    
    

    运行结果

    线程B:1
    线程B:2
    线程B:3
    线程A:1
    线程A:2
    线程A:3
    线程C:1
    线程C:2
    线程C:3
    
    Process finished with exit code 0
    
    
    

    使用join方法时

    public class TestDemo2 {
    
        public static void main(String[] args) {
           MyThread A = new MyThread("线程A",null);
           MyThread B = new MyThread("线程B",A);
           MyThread C = new MyThread("线程C",B);
            A.start();
            B.start();
            C.start();
        }
    }
        class MyThread extends Thread{
            private String name;
            private Thread thread;
    
            public MyThread(String name,Thread thread) {
                this.name = name;
                this.thread = thread;
            }
    
            @Override
            public void run(){
                if (thread != null){
                    try {
                        thread.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int i = 1;i <= 3;i++){
                    System.out.println(name +":" + i);
                }
            }
    
        }
    
    
    

    运行结果

    线程A:1
    线程A:2
    线程A:3
    线程B:1
    线程B:2
    线程B:3
    线程C:1
    线程C:2
    线程C:3
    
    Process finished with exit code 0
    
    

    5.wait,notify,notifyAll方法

    wait():调用某个对象的wait方法可以是当前线程阻塞
    调用当前对象notify/notifyAll才能唤醒这个对象所在的线程


    6.线程中断方法

    每个Java线程都会有一个中断状态位,程序可以检测这个中断状态位来判断该线程是否执行结束
    1.interrupt() (成员方法)由线程对象调用,将中断状态位置为true
    2.isInterrupted(成员方法)判断当前的中断状态为是否为true
    3.interrupted(静态方法)调用该方法会擦除中断状态位的标识
    ●如下方法能使当前线程进入阻塞状态,调用interrupt方法可以打断阻塞。这些方法被称为可打断方法
    Object.wait()/wait()
    Thread.sleep/Timeunit.***.sleep()
    Thread.join()/Thread.join()

    import java.util.concurrent.TimeUnit;
    
    public class TestDemo3 {
        public static void main(String[] args) {
            MyThread1 thread1 = new MyThread1();
            thread1.start();
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            thread1.interrupt();
            while (!thread1.isInterrupted()){
                System.out.println("线程中断");
            }
        }
    }
    
    class MyThread1 extends Thread{
        @Override
        public void run(){
            System.out.println("线程运行中");
        }
    }
    
    展开全文
  • 1.sleep()使当前线程(即调用该方法线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是如果有Synchronized同步块,其他线程仍然不同访问共享数据。注意该方法要捕获异常比如有两个线程...
  • 本文将带你讲诉Java多线程中的常用方法Java多线程中的常用方法有如下几个start,run,sleep,wait,notify,notifyAll,join,isAlive,currentThread,interrupt1)start方法用于启动一个线程,使相应的线程进入排队等待状态...
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼Windows操作系统,C语言实现多线程:#include#includeDWORDAPIENTRYThreadOne(LPVOIDthreadArg){printf("线程开始啦,参数是:%s\n",(char*)threadArg);return0;}intmain...
  • 1、线程常用方法 1.start() ①启动当前线程 ②调用当前线程的run()方法 2.run(),通常需要重写Thread类中的此方法,将创建的线程的声明要执行的操作声明在此方法中 3.currentThread():静态方法,返回当前代码执行...
  • Java线程常用方法汇总

    2021-02-28 16:22:30
    1、sleep()使当前线程(即调用该方法线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。例如有两个...
  • JAVA中多线程的实现方式和常用线程方法详解 JAVA实现多线程的三种方式 继承Thread类并且重写run方法 实现Runnable接口,并且实现接口中的run方法,使用Thread类的有参构造将实现类作为参数传入 实现Callable接口...
  • 线程常用方法 setName:设置线程名称 getName:返回线程名称 start:开始线程,JVM底层调用该线程的start0方法,start底层会创建新的线程,run就是一个简单的方法调用,并不会新建线程 run:调用线程对象的...
  • Java线程常用方法详解

    2021-02-26 17:03:26
    线程常用方法1.start(): 线程调用该方法将启动线程,使之从新建状态进入就绪队列排队,一旦轮到它来享用CPU资源时,就可以脱离创建它的线程独立开始自己的生命周期了。2.run(): Thread类的run()方法与Runnable...
  • java 线程常用方法

    2021-12-14 11:07:58
    创建(new)状态: 准备好了一个多线程的对象,即执行了new Thread(); 创建完成后就需要为线程分配内存 就绪(runnable)状态: 调用了start()方法, 等待CPU进行调度 运行(running)状态: 执行run()方法 阻塞...
  • java多线程有几种实现方法,都是什么?同步有几种实java中多线程的实现方法有两种:1.直接继承thread类;2.实现runnable接口;同步的实现方法有五种:1.同步方法;2.同步代码块;3.使用特殊域变量(volatile)实现线程...
  • Java多线程常用方法和关键字(自己容易忘记的和弄混的)1.Thread类常用方法:Thread MyThread = new Thread(mt,"线程名");-//sleep()使该线程进入阻塞状态,本身不会释放锁MyThread .sleep(millis);//毫秒数MyThread ....
  • 测试Thread中的常用方法: start():启动当前线程;调用当前线程的run() run(): 通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中 currentThread():静态方法,返回执行当前代码的...
  • java线程常用方法

    2021-03-06 01:13:58
    java线程常用方法编号方法说明1public void start()使该线程开始执行;Java 虚拟机调用该线程的 run 方法。2public void run()如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run ...
  • 一、同步(synchronized)和异步(asynchronized)1、同步(synchronized)简单说可以理解为共享的意思,如果资源不是共享的,就没...举个例子:线程1调用了带有synchronized关键字的方法methodA,线程2调用了异步方法me...
  • 线程常用方法 1.构造方法和属性的获取方法 构造方法: 属性的获取方法: 2.常用方法 <1>.run()和start() start();方法:启动线程 run();方法:覆写 run 方法是提供给线程要做的事情的指令清单 注意: run和...
  • 多线程常用方法 1. 取得和设置线程名称 在Thread类中,可以通过getName()方法取得线程的名称,通过setName()方法设置线程的名称。 线程的名称一般在启动线程前设置,但也允许为已经运行的线程设置名称。运行两个...
  • 文章目录多线程讲解一、线程状态迁移图二、Thread常用方法1.sleep2.yield3.join三、synchronized锁1.synchronized特性2.synchronized的三种应用方式3.synchronized锁的底层实现 一、线程状态迁移图 线程六种状态:...
  • 展开全部1、继承Thread,然后...API 上说62616964757a686964616fe78988e69d8331333361303666明如下:创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的run 方法。接下来可以...
  • 文章目录1、线程的状态2、线程间的状态转化3、线程常用方法(1)start()(2)sleep()(3)yield()(4)join()(5)interrupt()(6)Priority(7)wait()/notify()/notifyAll()4、线程调度 1、线程的状态 Java中线程...
  • 多线程实现的方式三三、多线程常用操作1.获取和设置线程对象名称2.线程调度及获取和设置线程优先级3.线程休眠4.守护线程5.中断线程6.线程礼让 前言 首先我们来看下面一段代码,了解单线程的概念。 public class ...
  • 常用函数(一)任务描述相关知识2sleep()函数join()函数编程要求测试说明代码示例第3关:常用函数(二)任务描述相关知识yield 函数wait 函数线程常用函数总结编程要求测试说明代码示例 第1关:线程的状态与调度 ...
  • 线程的创建方式线程常用方法 1.线程的概念 线程和进程的区别: 进程是系统分配资源的最小单位,线程是系统调度的最小单位。 一个进程内的线程之间是可以共享资源的。 每个进程至少有一个线程存在,即主线程。 注:...
  • Java多线程

    2021-02-28 06:03:31
    多线程应用程序的执行都是cpu在做着快速的切换完成的。这个切换是随机的1、进程直译:正在进行中的程序一个程序就是一个进程,而一个程序中的多个任务则被称为线程,进程其实就是一个静态的概念2、线程(控制单元/...
  • 一、OS模块os模块主要是对文件,目录的操作常用方法:os.mkdir() 创建目录os.removedirs() 删除文件os.getcwd() 获取当前目录os.path.exists(dir or file) 判断文件或者目录是否存在二、time模块time.asctime() 国外...
  • Java中的多线程常用方法(二)。1、void setName()方法作用:设置当前线程的名称。2、int getPriority()方法作用:获取当前线程的优先级。注:线程的优先级一共分为10个,分别用1到10表示。1表示最低优先级,5表示正常...
  • java中线程创建的两种常用方法 1.继承Thread 首先创建一个类继承Thread类,需要重写run方法。run方法就是线程要执行的任务,在run方法中让这个线程循环打印10次"子线程正在执行" public class MyThread extends ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 559,942
精华内容 223,976
关键字:

多线程常用方法