java之多线程

java之多线程简介:线程(thread)就是进程中的一个执行线索。Java虚拟机允许进程中同时执行多个线程。每个线程都有一个优先级。具有较高优先级的线程先执行。线程是操作系统分配CPU时间的基本实体。每一个

大家好,又见面了,我是你们的朋友全栈君。

简介

  线程(thread)就是进程中的一个执行线索。Java虚拟机允许进程中同时执行多个线程。每个线程都有一个优先级。具有较高优先级的线程先执行。
  线程是操作系统分配 CPU 时间的基本实体。每一个应用程序至少有一个线程,也可以拥有多个线程。线程是程序中的代码流。多个线程可以同时运行并能共享资源。
  线程与进程不同,每个进程都需要操作系统为其分配独立的地址空间,而同一进程中的各个线程是在同一块地址空间中工作。

线程存在一个生命周期,由以下方法体现

  (1)  start()方法:启动一个线程。
  (2)  run()方法:定义该线程的动作。
  (3)  sleep()方法:使线程睡眠一段时间,单位为ms。
  (4)  suspend()方法:使线程挂起。
  (5)  resume()方法:恢复挂起的线程。
  (6)  yield()方法:把线程移到队列的尾部。
  (7)  stop()方法:结束线程生命周期并执行清理工作。
  (8)  destroy()方法:结束线程生命周期但不做清理工作。
       其中最常用的是方法start()、run()、sleep()、stop()。

线程的生命周期包含5个阶段,包括:新建、就绪、运行、阻塞、销毁。

  • 新建:就是刚使用new方法,new出来的线程;

  • 就绪:就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;

  • 运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run方法定义了线程的操作和功能;

  • 阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep()、wait()之后线程就处于了阻塞状态,这个时候需要其他机制将处于阻塞状态的线程唤醒,比如调用notify或者notifyAll()方法。唤醒的线程不会立刻执行run方法,它们要再次等待CPU分配资源进入运行状态;

  • 销毁:如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源;

JAVA 线程实现/创建方式

1、继承 Thread 类

  Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方 法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线 程,并执行 run()方法。

1 public class MyThread extends Thread { 2     public void run() { 3         System.out.println("MyThread.run()"); 4  } 5 } 6 
7 MyThread myThread1 = new MyThread(); 8 myThread1.start();    

2、实现 Runnable 接口

  如果自己的类已经 extends 另一个类,就无法直接 extends Thread,此时,可以实现一个 Runnable 接口。

 1 public class MyThread extends OtherClass implements Runnable {  2     public void run() {  3         System.out.println("MyThread.run()");  4  }  5 }  6 
 7 //启动 MyThread,需要首先实例化一个 Thread,并传入自己的 MyThread 实例:
 8 MyThread myThread = new MyThread();  9 Thread thread = new Thread(myThread); 10 thread.start(); 11 
12 //事实上,传入一个 Runnable target 参数给 Thread 后,Thread 的 run()方法就会调用target.run()
13 public void run() { 
14   if (target != null) {
15     target.run();
16   }  

17 }  

3、通过Callable和Future创建有返回值线程

  有返回值的任务必须实现 Callable 接口,类似的,无返回值的任务必须 Runnable 接口。执行 Callable 任务后,可以获取一个 Future 的对象,在该对象上调用 get 就可以获取到 Callable 任务 返回的 Object 了。

 1 /*
 2  * 首先说一下步骤:
 3  * 1.创建Callable接口的实现类,并实现call()方法,该call()方法将作为
 4  *         线程执行体,并且有返回值。
 5  * 2.创建Callable实现类的实例,使用FutureTask类来包装Callable对象,
 6  *      该FutureTask对象封装了Callable对象的call()方法的返回值。
 7  * 3.使用FutureTask对象作为Thread对象的target创建并启动新线程。
 8  * 4.调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
 9  */
10 class MyCallable implements Callable<Integer> {
11 
12     @Override
13     public Integer call() throws Exception {
14         // 线程需要完成的任务
15         return new Random().nextInt(100);
16     }
17 }
18 
19 public static void main(String[] args) {
20     MyCallable myCallable = new MyCallable();
21     FutureTask<Integer> futureTask = new FutureTask<>(MyCallable);
22     new Thread(futureTask).start();
23     // 可能做一些其他操作
24     try {
25         System.out.println("子线程的返回值:" + futureTask.get());
26     } catch (Exception e) {
27         System.out.println(e.getMessage());
28     }
29 }

4、基于线程池的方式

上面三种方式的案例都是通过 new Thread 进行创建的,其弊端如下:

  • 每次new Thread新建对象性能差。
  • 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机。
  • 缺乏更多功能,如定时执行、定期执行、线程中断。

线程资源是非常宝贵的资源。那么每次需要的时候创建,不需要的时候销毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。其优势如下:

  • 重用存在的线程,减少对象创建、消亡的开销,性能佳。
  • 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
  • 提供定时执行、定期执行、单线程、并发数控制等功能

线程池结合Runnable接口,如下

 1 // 创建线程池
 2 ExecutorService threadPool = Executors.newFixedThreadPool(10);
 3 while(true) {
 4     threadPool.execute(new Runnable() { // 提交多个线程任务,并执行
 5         @Override
 6         public void run() {
 7             System.out.println(Thread.currentThread().getName() + " is running ..");
 8             try {
 9                 Thread.sleep(3000);
10             } catch (InterruptedException e) {
11                 e.printStackTrace();
12             }
13         }
14     });
15 }

线程池结合Callable接口,如下:

 1 //创建一个线程池
 2 ExecutorService pool = Executors.newFixedThreadPool(taskSize);
 3 // 创建多个有返回值的任务
 4 List<Future> list = new ArrayList<Future>(); 
 5 for (int i = 0; i < taskSize; i++) { 
 6     Callable c = new MyCallable(i + " "); 
 7     // 执行任务并获取 Future 对象
 8     Future f = pool.submit(c); 
 9     list.add(f); 
10 } 
11 // 关闭线程池
12 pool.shutdown(); 
13 // 获取所有并发任务的运行结果
14 for (Future f : list) { 
15     // 从 Future 对象上获取任务的返回值,并输出到控制台
16     System.out.println("res:" + f.get().toString()); 
17 } 

 

关于使用线程池管理线程,可单列一篇,详情可参考:

https://www.cnblogs.com/ymzsb/p/14881753.html

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/154771.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • nginx负载均衡配置详解_负载均衡算法实现

    nginx负载均衡配置详解_负载均衡算法实现1.简单介绍负载均衡如果你的nginx服务器给2台web服务器做代理,负载均衡算法采用轮询,那么当你的一台机器web程序关闭造成web不能访问,那么nginx服务器分发请求还是会给这台不能访问的web服务器,如果这里的响应连接时间过长,就会导致客户端的页面一直在等待响应,对用户来说体验就打打折扣,这里我们怎么避免这样的情况发生呢。这里我配张图来说明下问题。如果负载均衡中其中web2发生这样的…

    2022年10月12日
  • onpropertychange替代方案[通俗易懂]

    onpropertychange替代方案1.onpropertychange的介绍onpropertychange事件就是property(属性)change(改变)的时候,触发事件。这是IE专有的!如果想兼容其它浏览器,有个类似的事件,oninput!可能大家会想到另外一个事件:onchange。但是,onchange有两个弊端。一、就是它在触发对象失去焦点时,才触发onchange事件。二、如果得用javascript改变触发对象的属性时,并不能触发onchange事件,oninput也

  • Windows Server 2008R2 SP1 动态内存

    Windows Server 2008R2 SP1 动态内存

  • 解决ModuleNotFoundError: No module named ‘pip‘问题

    解决ModuleNotFoundError: No module named ‘pip‘问题Python学习遇到小问题:ModuleNotFoundError:Nomodulenamed‘pip’今天想要装一下wxPython第三方库来写一下Python的GUI的时候发现cmd窗口下无法执行pip命令,想了想昨晚好像是pip命令行提示了我有新版本可以更新使用,更新之后也不成功,但昨晚没有怎么理会,以为没事,但今早起来一看发现pip命令都用不了了,出现了ModuleNotFoun…

  • Cocoa Iphone 屏幕尺寸

    Cocoa Iphone 屏幕尺寸 1、状态栏:通常是20px高,在打电话或显式消息时,放大到40px。因此,在纵向模式下,应用程序的可用空间是320×460,横向模式下是480×300; 2、导航栏:通常情况下,纵向模式下是44px,横向模式下是32px。在提示模式下(不太常用),是74px,不管是纵向还是横向。 3、选项卡栏:不管纵向还是横向,都是48px。 4、工具栏:不管纵向还是很想,都是44px。 5、[

  • 大数据降噪方法论

    大数据降噪方法论部分机构掌握了一定量的客户信息数据,就以为掌握了大数据,忽视对数据分析工具和方法论的研究。在金融业务中,这有可能影响其对风险的识别和防控,并造成风险的积聚和扩散。最近,《互联网金融风险专项整治工作实施方案》全文网上曝光,包括第三方支付、P2P网贷、股权众筹、互联网保险、投资理财,以及互联网跨界资管,甚至互联网广告,都将面临一轮集中整治。分析整治的原因…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号