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

作者:中华雪碧 时间:2022-01-03 01:02:28 

之前有简单介绍过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执行完,再执行

来源:https://segmentfault.com/a/1190000012213171

标签:java,多线程代码,thread
0
投稿

猜你喜欢

  • Spring AOP如何整合redis(注解方式)实现缓存统一管理详解

    2023-11-19 06:09:27
  • 使用@Order控制配置类/AOP/方法/字段的加载顺序详解

    2023-09-05 17:34:35
  • 关于LinkedList集合对元素进行增查删操作

    2022-09-23 11:48:45
  • SpringMVC编程使用Controller接口实现控制器实例代码

    2023-02-01 02:03:36
  • 使用IDEA开发配置Java Web的初始化过程

    2022-09-25 16:33:38
  • Java解析Excel内容的方法

    2023-03-20 20:36:26
  • 详谈Java中net.sf.json包关于JSON与对象互转的坑

    2023-03-02 12:38:31
  • Java实现MD5消息摘要算法

    2023-06-18 06:37:35
  • java中Memcached的使用实例(包括与Spring整合)

    2021-11-28 13:29:06
  • 简单实现安卓里百度地图持续定位

    2023-07-29 07:59:22
  • 如何使用MybatisPlus快速进行增删改查详解

    2023-11-03 06:58:13
  • Java中ArrayList与顺序表的定义与实现方法

    2022-06-08 03:27:12
  • 详解Java中运算符及用法

    2023-11-29 08:17:57
  • IDEA不编译除了.java之外的文件的解决办法(推荐)

    2023-09-16 15:50:44
  • Java8中Optional类的使用说明

    2023-07-25 13:31:32
  • java导出Excel通用方法实例

    2023-10-27 04:43:33
  • servlet异步请求的实现

    2023-07-14 17:11:38
  • Java日常练习题,每天进步一点点(2)

    2023-08-17 22:46:19
  • 解决Spring Cloud Feign 请求时附带请求头的问题

    2022-12-11 04:29:46
  • 如何利用java控制鼠标操作一些重复的事情

    2021-11-12 12:54:02
  • asp之家 软件编程 m.aspxhome.com