java多线程Thread的实现方法代码详解

 更新时间:2017年11月30日 15:16:17   作者:中华雪碧  
这篇文章主要介绍了java多线程Thread的实现方法代码详解,涉及start(),run(),stop(),interrupt(),isInterrupted(),join()和join(long millis)等方法的介绍,具有一定借鉴价值,需要的朋友可以了解下。

之前有简单介绍过java多线程的使用,已经Thread类和Runnable类,为了更好地理解多线程,本文就Thread进行详细的分析。

start()

我们先来看看API中对于该方法的介绍:

使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。

多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。

start方法是开启线程的方法,使用后java会创建一个新的线程执行run里的方法。这是一个小demo:

    for(int i=0;i<3;i++){
      Thread t= new Thread(new Runnable() {
        @Override
        public void run() {
      System.out.println(Thread.currentThread().getName()+" start");
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
      System.out.println(Thread.currentThread().getName()+" end");
        }
      });
      t.start();
    }
    System.out.println("it is over");

执行结果:
it is over
Thread-1 start
Thread-0 start
Thread-2 start
Thread-0 end
Thread-1 end
Thread-2 end

由于多线程是有随机性的,所以每次的结果可能都不一样,这一点也是我们需要注意的,线程的执行顺序和调用顺序并不一致。

run()

run方法就是调用Thread设置的Runnable的run方法,将上面的demo进行修改:

    for(int i=0;i<3;i++){
      Thread t= new Thread(new Runnable() {
        
        @Override
        public void run() {
      System.out.println(Thread.currentThread().getName()+" start");
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
      System.out.println(Thread.currentThread().getName()+" end");
        }
      });
      t.run();
    }
    System.out.println("it is over");

执行结果:
main start
main end
main start
main end
main start
main end
it is over
run方法的直接结果和start有很大的差别,完全是按顺序执行,并没有开启新线程。

stop()

stop方法是强制停止线程的执行,是非安全的,不要使用此方法。在调用stop时, 会对锁定的资源进行释放,但这种释放是非一致的,容易引起程序问题。如果想要控制线程的停止,可以使用自定义变量来判断或者isInterrupted()方法:

class Thread1 extends Thread {
  @Override
  public void run() {
    //判断线程体是否运行
    while (!isInterrupted()) {
      // Do Something
    }
  }  
}

interrupt()

interrupt的作用是通知线程,你已经被中断的,但具体的中断执行需要在线程自定义处理,甚至你可以不理会继续执行。具体的中孤单是会线程执行join、wait、sleep方法时,抛出InterruptedException。

Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" start");
            try {
              for(int i=0;i<100000;i++){
                System.out.println(i+"");
                Thread.sleep(1);
              }
            } catch (InterruptedException e) {
              System.out.println("the thread is interrupted");//可以在这里做资源释放,日志记录等
              e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" end");
          }
      });
      t1.start();
      Thread.sleep(100);
      t1.interrupt();

执行结果:

65
66
67
68
the thread is interrupted
java.lang.InterruptedException: sleep interrupted
Thread-0 end
  at java.lang.Thread.sleep(Native Method)
  at com.wk.aqi.act.Test$1.run(Test.java:23)
  at java.lang.Thread.run(Thread.java:745)

isInterrupted()

判断线程是否中断,在执行上面的interrupt方法后,会return true。

setPriority(int newPriority)和getPriority()
设置线程的优先级和获取线程的优先级,cpu分配的资源给侧重给priority高的线程。

Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            long t = System.currentTimeMillis();
            System.out.println(Thread.currentThread().getName()+" start");
            for(int i=0;i<1000;i++){
              try {
                Thread.sleep(1);
              } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
              }
            }
            System.out.println(Thread.currentThread().getName()+" t1 end "+(System.currentTimeMillis()-t));
          }
      });
      Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
          long t = System.currentTimeMillis();
          System.out.println(Thread.currentThread().getName()+" start");
          for(int i=0;i<1000;i++){
            try {
              Thread.sleep(1);
            } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
          }
          System.out.println(Thread.currentThread().getName()+" t2 end "+(System.currentTimeMillis()-t));
        }
      });
      t1.setPriority(10);
      t2.setPriority(1);
      t2.start();
      t1.start();

执行结果:

Thread-0 start
Thread-1 start
Thread-0 t1 end 1357
Thread-1 t2 end 1371

在优先级一样的情况下,t1和t2是几乎同时完成的,在优先级不一样的情况,有明显的差别。

getName()

比较简单,获取线程的名称。

join()和join(long millis)

jion方法的作用是等待线程执行完成,join(long millis)可以设置最长等待时间。比如主线程需要等待子线程完成,获取子线程的结果后才能继续往下执行,这时候就可以使用join方法

Thread t1 = new Thread(new Runnable() {
      @Override
      public void run() {
          long t = System.currentTimeMillis();
          System.out.println(Thread.currentThread().getName()+" start");
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
          System.out.println(Thread.currentThread().getName()+" t1 end "+(System.currentTimeMillis()-t));
        }
    });
    t1.start();
    t1.join();
    System.out.println("等待t1执行完,再执行");

执行结果:

Thread-0 start
Thread-0 t1 end 1001
等待t1执行完,再执行

总结

以上就是本文关于java多线程Thread的实现方法代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。

相关文章

  • SpringBoot接口限流的实现方法小结

    SpringBoot接口限流的实现方法小结

    在一个高并发系统中对流量的把控是非常重要的,当巨大的流量直接请求到我们的服务器上没多久就可能造成接口不可用,不处理的话甚至会造成整个应用不可用,所以我们需要接口限流,本文给大家介绍了SpringBoot接口限流的实现方法,需要的朋友可以参考下
    2024-10-10
  • Java发送邮件javax.mail的实现方法

    Java发送邮件javax.mail的实现方法

    这篇文章主要为大家介绍了Java发送邮件javax.mail的实现方法,具有一定的参考价值,代码都有详细的注释,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • java开发分布式服务框架Dubbo服务引用过程详解

    java开发分布式服务框架Dubbo服务引用过程详解

    这篇文章主要为大家介绍了java开发分布式服务框架Dubbo服务引用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Eclipse 开发java 出现Failed to create the Java Virtual Machine错误解决办法

    Eclipse 开发java 出现Failed to create the Java Virtual Machine错误

    这篇文章主要介绍了Eclipse 开发java 出现Failed to create the Java Virtual Machine错误解决办法的相关资料,需要的朋友可以参考下
    2017-04-04
  • 从零到掌握Spring Boot Validation 接口校验的详细过程

    从零到掌握Spring Boot Validation 接口校验的详细过程

    本文详细介绍了SpringBoot的Validation接口校验机制,包括其核心功能、常用注解、自定义校验、以及实际应用场景,通过注解定义数据校验规则,感兴趣的朋友跟随小编一起看看吧
    2025-02-02
  • restTemplate未设置连接数导致服务雪崩问题以及解决

    restTemplate未设置连接数导致服务雪崩问题以及解决

    面对线上问题,仔细分析原因,及时调整配置,能有效解决问题,本文详细描述了线上遇到流量突增引发的问题,通过查看代码和连接池信息,分析出问题的原因是连接池满了,连接池大小配置不足以应对大并发流量,通过调整连接池大小配置
    2024-10-10
  • Java Spring框架简介与Spring IOC详解

    Java Spring框架简介与Spring IOC详解

    Spring 框架是一个轻量级的解决方案,可以一站式地构建企业级应用。它是为了解决 企业应用开发的复杂性而创建的。Spring 使用基本的 JavaBean 来完成以前只可能由 EJB 完成的事情。IOC 是 Inversion of Control 的缩写,多数书籍翻译成控制反转
    2021-09-09
  • idea向System.getenv()添加系统环境变量的操作

    idea向System.getenv()添加系统环境变量的操作

    这篇文章主要介绍了idea向System.getenv()添加系统环境变量的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Spring 4.1+JSONP的使用指南

    Spring 4.1+JSONP的使用指南

    在解释JSONP之前,我们需要了解下”同源策略“,这对理解跨域有帮助。基于安全的原因,浏览器是存在同源策略机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载额文档的属性。说的简单点就是浏览器限制脚本只能和同协议、同域名、同端口的脚本进行交互。
    2016-04-04
  • SpringBoot使用Minio进行文件存储的实现

    SpringBoot使用Minio进行文件存储的实现

    本文主要介绍了SpringBoot使用Minio进行文件存储的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07

最新评论