java 多线程:Thread类常用方法:setPriority优先级、interrupt中断标记、suspend暂停与唤醒resume(已过时);daemon守护线程

常用方法:

  • boolean isAlive() 测试此线程是否存活。
  • boolean isDaemon() 测试此线程是否为守护程序线程。
  • static void sleep?(long millis) 导致当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,具体取决于系统计时器和调度程序的精度和准确性。
  • static void sleep?(long millis, int nanos) 导致当前正在执行的线程休眠(暂时停止执行)指定的毫秒数加上指定的纳秒数,具体取决于系统定时器和调度程序的精度和准确性。
  • void start() 导致此线程开始执行; Java虚拟机调用此线程的run方法。
  • Thread.State getState() 返回此线程的状态。
  • void join() 等待这个线程死亡。
  • void join?(long millis) 此线程最多等待 millis毫秒。
  • void join?(long millis, int nanos) 此线程最多等待 millis毫秒加上 nanos纳秒。
  • long getId() 返回此Thread的标识符。
  • String getName() 返回此线程的名称。
  • int getPriority() 返回此线程的优先级。
  • static void yield() 向调度程序提示当前线程是否愿意产生其当前使用的处理器

interrupt方法:

interrrpt方法只是做了一个标记,标记这个线程可以结束了,但是实际上要怎么结束,需要我们程序员自己处理。那我们怎么判断你是不是用interrrpt方法做了一个标记呢?用isInterrrpted方法来判断。
  • 想要停止run方法里面的所有代码,可以用return

yield方法的作用:

yield方法的作用是让当前正在运行的线程放弃CPU资源,让给其他线程使用。

/**
 * @ClassName ThreadYileldExample
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/4/21.
 */
public class ThreadYileldExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            int num = 0;
            long beginTime = System.currentTimeMillis();
            for(int i=0; i<1000000; i ++){
                num++;
                //Thread.yield();
            }
            long endTime = System.currentTimeMillis();
            System.out.println("计算耗时:" + (endTime - beginTime) + "ms");
        });
        thread.start();
    }
}

 线程优先级应用setPriority

1,在操作系统中,线程是具有优先级的。系统会把CPU资源优先给优先级高的线程使用。
2,JAVA中优先级具有继承性,子类会默认继承父类的优先级。比如先线程A中启动了一个线程B那么线程B具有和A一样的优先级。
结果:在没有设置优先级的情况下,线程谁先运行完,他们的概率其实是一样的。但是调用了setPriprity方法之后,值更大的大概率会优先完成。
public class ThreadPriorityExample {
    public static void main(String[] args) {
        Runnable r = () -> {
            for (int i=0; i<500; i++){
                System.out.println("线程:" + Thread.currentThread().getName() + ",运行到" + i);
            }
            System.out.println("线程:" + Thread.currentThread().getName() + ",运行结束");
        };
        Thread threadA = new Thread(r,"A");
        Thread threadB = new Thread(r,"B");
        threadA.setPriority(8);
        threadB.setPriority(2);
        threadA.start();
        threadB.start();
    }
}

注意:
CPU会优先分配给线程优先级比较高的线程使用,但是,这并不表示优先级高的线程一定是先运行完成了之后才会运行优先级比较低的使用。线程优先级低的一样具有CPU的使用权限。所以我们可以发现我们设置线程优先级,只是告诉我们的JVM,优先级高的线程具有优先运行的趋势,但是这个并不表示他实际运行的时候就一定优先完成。
这个就好比,在我们学习中,有的同学是智商比较高,记忆力又非常好,有的同学可能要差一些。我们只能说智商比较高的同学经过学习之后,他考试的成绩应该比智商低一些同学好的概率要大一些。但是这并不表示他一定就会考得更好。我们智商差一些的同学经过自己的努力学习,加班加点之后,依然可以拿到更好的分数。

守护线程:setDaemon(true)

JAVA中有两种线程,一种是用户线程,一种收守护线程。
守护线程一种特殊的线程,他具有陪伴的意义。当系统中不存在用户线程了之后,守护线程也就随之会销毁。典型的守护线程就是JVM的垃圾回收,如果所有的用户线程都销毁了,那么也就没有任何东西可以被垃圾回收期回收了。这个时候垃圾回收器也会随之销毁。
子线程为守护线程示例:(子线程无下属的非守护线程,自动退出不会运行子线程代码
public class DaemonThreadTest {
    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //设置为守护线程之后,这个代码就不会运行
                System.out.println("我是子线程,我运行完了");
            }
        };
        //设置线程为守护线程
        thread.setDaemon(true);
        thread.start();
        System.out.println("我是主线程我运行完了。");
    }
}

daemon线程有子用户线程示例:(父级线程都会等待用户线程退出)

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Random;

/**
 * @ClassName ThreadDaemonExample
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/4/21.
 */
public class ThreadDaemonExample {
    public static void main(String[] args) {
        /**
         * 设置为守护线程的子线程
         */
        Runnable runnable = () -> {

            Thread subThread = new Thread(){
                /**
                 * 子线程中的非守护孙子线程
                 */
                @Override
                public void run() {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("睡两秒的孙子线程结束了");
                }
            };
            //孙子线程设置为用户线程
            subThread.setDaemon(false);
            subThread.start();
            System.out.println("子线程运行....");

            //子线程执行任务
            String filePath = "多线程/src/daemonThreadOutput/subDaemonThreadOut.txt";
            try {
                System.setOut(new PrintStream(new FileOutputStream(filePath)));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            System.out.println("我是子线程,我运行完了");
        };
        /** 孙子线程为用户线程,main线程为父线程,main线程也不会退出,
         * filePath文件内成功写入:
         * 我是子线程,我运行完了
         * 睡两秒的孙子线程结束了
         */

        Thread thread = new Thread(runnable,"子线程");
        thread.setDaemon(true);
        thread.start();
        System.out.println(Thread.currentThread().getName() + "运行完了");
    }
}

暂停和唤醒线程(已过时)

  • 1,suspend():暂停线程
  • 2,resume():恢复线程
/**
 * @ClassName ThreadSuspendExample
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/4/21.
 */
public class ThreadSuspendExample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread() {
            @Override
            public void run() {
                int num = 0;
                while (true) {
                    System.out.println("num is " + (num ++));
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        thread.start();
        System.out.println(Thread.currentThread().getName() + "开始睡眠5S");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+"睡眠结束,我要暂停子线程了...然后再睡5S");
        thread.suspend();//暂停线程
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+"睡眠结束,我要恢复子线程了...");
        thread.resume();
    }
}

API文档方法:

 

原文地址:https://www.cnblogs.com/zhangmingda/p/14686531.html