首页 > 编程语言 >Java多线程技能-方法介绍

Java多线程技能-方法介绍

时间:2023-02-22 20:12:13浏览次数:34  
标签:技能 Java Thread System 线程 println 多线程 public out

java 多线程技能

技术点:

  • 线程的启动
  • 如何使线程暂停
  • 如何使线程停止
  • 线程的优先级
  • 线程安全相关的问题

方法 currentThread()

currentThread() 方法可返回代码段正在被哪个线程调用。

public class MyThread extends Thread {

    public MyThread() {
        System.out.println("构造方法的打印:" + Thread.currentThread().getName());
    }

    @Override
    public void run() {
        System.out.println("run 方法的打印:" + Thread.currentThread().getName());
    }
}
public class Run {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start(); // 执行 run() 方法时机不确定时,启动新的线程
        //myThread.run(); // 立即执行 run() 方法,不启动新线程
    }
}

图示:image-20230222142407912.

方法 isAlive()

isAlive() 方法的功能是判断线程对象是否存活(测试线程是否处于活动状态)。

那什么是活动状态呢?

答:线程已经启动且尚未终止。如果线程处于正在运行或准备开始运行的状态,就认为线程是 “存活” 的。


注意:关键字 this 代表 this 所在类的对象。

public class CountOperate extends Thread {
    public CountOperate() {
        System.out.println("CountOperate---begin");
        System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());
        System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive());
        System.out.println("this.getName()=" + this.getName());
        System.out.println("this.isAlive()=" + this.isAlive());
        System.out.println("CountOperate---end\n");
    }

    @Override
    public void run() {
        System.out.println("\nrun---begin");
        System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());
        System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive());
        System.out.println("this.getName()=" + this.getName());
        System.out.println("this.isAlive()=" + this.isAlive());
        System.out.println("run---end");
    }
}
public class Run {
    public static void main(String[] args) {
        CountOperate c = new CountOperate();
        Thread t1 = new Thread(c);
        System.out.println("main begin t1 isAlive=" + t1.isAlive());
        t1.setName("A");
        t1.start();
        System.out.println("main end t1 isAlive=" + t1.isAlive());
    }
}

图示:image-20230222145327900.

方法 sleep(long millis)

sleep() 方法的作用是在指定的毫秒数内让当前 “正在执行的线程” 休眠(暂停执行),这个 “正在执行的线程” 是指 this.currentThread() 返回的线程。

public class MyThread extends Thread {

    @Override
    public void run() {
        try {
            System.out.printf("run threadName=%s begin=%d\n", Thread.currentThread().getName(), System.currentTimeMillis());
            Thread.sleep(2000);
            System.out.printf("run threadName=%s end=%d\n", Thread.currentThread().getName(), System.currentTimeMillis());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
public class Run {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        System.out.printf("begin=%d\n", System.currentTimeMillis());
        myThread.start();
        System.out.printf("end=%d\n", System.currentTimeMillis());
    }
}

方法 sleep(long millis, int nanos)

public static void sleep(long millis, int nanos) 方法的作用是让当前正在执行的线程在指定的毫秒数加指定的纳秒数内休眠(暂停执行),此操作受到系统计时器及调度程序精度及准确性的影响。

public class Run {
    public static void main(String[] args) throws InterruptedException {
        long beginTime = System.currentTimeMillis();
        Thread.sleep(2000, 999999);
        long endTime = System.currentTimeMillis();
        System.out.println(endTime - beginTime);
    }
}

方法 StackTraceElement[] getStackTrace()

public StackTraceElement[] getStackTrace() 方法的作用是返回一个表示该线程的堆栈跟踪元素数组。如果该线程尚未启动或已经终止,则该方法将返回一个零长度数组。如果返回的数组不是零长度的,则其第一个元素代表堆栈顶,它是该数组中最新的方法调用。最后一个元素代表堆栈底,是该数组中最旧的方法调用。

public class Run {
    public static void main(String[] args) {
        new Run().a();
    }

    public void a() {
        b();
    }

    private void b() {
        c();
    }

    private void c() {
        d();
    }

    private void d() {
        e();
    }

    private void e() {
        StackTraceElement[] array = Thread.currentThread().getStackTrace();
        for (int i = 0; i < array.length; i++) {
            StackTraceElement eachElement = array[i];
            System.out.printf("className=%s methodName=%s fileName=%s lineNumber=%s\n",
                    eachElement.getClassName(), eachElement.getMethodName(), eachElement.getFileName(), eachElement.getLineNumber());
        }
    }
}

图示:image-20230222175610145.

方法 static void dumpStack()

public static void dumpStack() 方法的作用是将当前线程的堆栈信息输出至标准错误流。该方法仅用于调试。

public class Run {
    public static void main(String[] args) {
        new Run().a();
    }

    public void a() {
        b();
    }

    private void b() {
        c();
    }

    private void c() {
        d();
    }

    private void d() {
        e();
    }

    private void e() {
        int age = 0;
        age = 100;
        if (age == 100) {
            Thread.dumpStack();
        }
    }
}

图示:image-20230222180131670.

方法 Map<Thread, StackTraceElement[]> getAllStackTraces()

Map<Thread, StackTraceElement[]> getAllStackTraces() 方法的作用是返回所有活动线程的堆栈信息的一个映射。Map 的 key 是线程对象,而 Map 的 value 是一个 StackTraceElement 数组,该数组表示相应 Thread 的堆栈信息。在调用该方法的同时,线程可能也在执行。每个线程的堆栈信息仅代表线程当时状态的一个快照。

public class Run {
    public static void main(String[] args) {
        new Run().a();
    }

    public void a() {
        b();
    }

    private void b() {
        c();
    }

    private void c() {
        d();
    }

    private void d() {
        e();
    }

    private void e() {
        Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
        if (map.size() != 0) {
            Iterator<Thread> keyIterator = map.keySet().iterator();
            while (keyIterator.hasNext()) {
                Thread eachThread = keyIterator.next();
                StackTraceElement[] array = map.get(eachThread);
                System.out.println("------每个线程的基本信息");
                System.out.println("\t线程名称:" + eachThread.getName());
                System.out.println("StackTraceElement[].length=" + array.length);
                System.out.println("\t线程状态:" + eachThread.getState());
                if (array.length != 0) {
                    System.out.println("\t打印 StackTraceElement[] 数组具体信息:");
                    for (int i = 0; i < array.length; i++) {
                        StackTraceElement eachElement = array[i];
                        System.out.println("\t" + eachElement.getClassName() + " "
                                + eachElement.getMethodName() + " " + eachElement.getFileName() + " "
                                + eachElement.getLineNumber());
                    }
                } else {
                    System.out.println("\t没有 StackTraceElement[] 信息,因为线程" + eachThread.getName() 
                            + " 中的 StackTraceElement[].length==0");
                }
                System.out.println();
                System.out.println();
            }
        }
    }
}

图示:image-20230222194831606.

方法 getId()

getId() 方法可以取得线程的唯一数字标识。

public class Run {
    public static void main(String[] args) {
        Thread runThread = Thread.currentThread();
        System.out.println(runThread.getName() + " " + runThread.getId());
        Thread t1 = new Thread();
        System.out.println(t1.getName() + " " + t1.getId());
        Thread t2 = new Thread();
        System.out.println(t2.getName() + " " + t2.getId());
        Thread t3 = new Thread();
        System.out.println(t3.getName() + " " + t3.getId());
    }
}

图示:image-20230222195306999.

从运行结果来看,当前执行代码的线程名为 main,线程 id 值为 1。

而 Thread-0 线程的 id 值直接到达 20,说明中间有 18 个id 值被隐藏的线程占有。

标签:技能,Java,Thread,System,线程,println,多线程,public,out
From: https://www.cnblogs.com/rnny/p/17145695.html

相关文章

  • Java-模块化
    模块的基本使用模块使用步骤创建模块(创建模块,创建包,创建类,定义方法)-创建两个模块myOne,myTwo在模块的src目录下创建module-info.java的描述性文件,该文件专门定义模块......
  • 多线程 龟兔赛跑案例
    packagecom.Java;publicclassRaceimplementsRunnable{//胜利者privatestaticStringwinner;@Overridepublicvoidrun(){for(inti=0......
  • IDEA打开项目代码,识别不了资源文件(java文件、yml文件等),找不到或无法加载主类 com.xxxx
    如图所示,识别不了java文件和yml文件   点开EditConfigurations发现找不到启动类  运行会报错:  可以尝试如下解决办法办法:        然......
  • java多线程:详解JUC
    对应狂神说JUC视频1.JUC是什么java.util下的几个包的简称涉及到多线程的开发java.util.concurrentjava.util.atomicjava.util.concurrent.locks2.线程和进程进程:多个程序......
  • Java ”框架 = 注解 + 反射 + 设计模式“ 之 注解详解
    Java”框架=注解+反射+设计模式“之注解详解每博一文案刹那间我真想令时光停住,好让我回顾自己,回顾失去的年华,缅怀哪个穿一身短小的连衣裙和瘦窄的短衫的小......
  • java中定义一个类可以同时继承两个类
    转载:百度知道(baidu.com)java中一个类不能直接继承两个类。比如说这样:classAextendsB,C不能这样写,因为java不支持多继承,但是可以像下面这样实现继承多个类:classAext......
  • Java里的对象是咋回事
    前言在上一篇文章中,壹哥给大家介绍了Java中的类及其特点、创建过程等内容,相信你现在已经知道该如何创建一个Java类了。接下来在本篇文章中,壹哥会继续带大家学习面向对象中......
  • Java的多线程+Socket
    客户端: packagecom.wulala;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net......
  • 解决java.lang.NoClassDefFoundError:Could not initialize class net.sf.cglib.beans
    异常描述项目引入Alibaba的EasyExcel工具,编译没有报错,在请求导出Excel文件的接口时,log异常出现以下错误java.lang.NoClassDefFoundError:Couldnotinitializeclassnet.......
  • Java常用类之Object源码分析
    一、概述理论上Object类是所有类的父类,即直接或间接的继承java.lang.Object类。由于所有的类都继承在Object类,因此省略了extendsObject关键字。Object类属于java.lang包......