Java基础---多线程(二)

线程的状态(6种)

新建:线程刚被创建,但是并未启动。还没调用start方法。

可运行:线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器。---已经调用了start方法启动了线程,线程可能在执行任务,也可能没有执行任务。

锁阻塞:当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。---当线程没有获得锁对象就会处于锁阻塞状态,如果获得锁对象,就会处于可运行状态。

无限等待:一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入Waiting状态。
通过wait()方法进入这个状态后是不能自动唤醒的,必须等待另一个线程调用notify或者notifyAll方法才能够唤醒。

计时等待:同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。
这一状态将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep 、Object.wait。

死亡状态:因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。---线程处于终止状态

线程状态之间的相互切换
在这里插入图片描述
实现无限等待:

1.使用锁对象调用wait方法使得线程进入无限等待
2.无限等待线程想要被唤醒,那么必须是其他线程使用锁对象调用notify方法或者notifyAll方法
3.调用wait方法和调用notify方法或notifyAll方法的锁对象必须一致
4.线程进入无限等待之后就不会抢占cpu资源,也不会争夺锁对象
5.线程进入无限等待之后,如果被唤醒了并且获取了锁对象,那就会从进入无限等待的位置继续往下执行---即从哪里醒来从哪里开始

在这里插入图片描述

等待唤醒机制

线程间通信:
概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不同

为什么要处理线程间通信:

 多个线程并发执行时, 在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务,并且我们希望他们有规律的执行, 那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。

如何实现线程间的有效通信:等待唤醒机制

等待唤醒机制:一个线程进行了规定操作后,就进入等待状态(wait()), 等待其他线程执行完他们的指定代码过后 再将其唤醒(notify());
在有多个线程进行等待时, 如果需要,可以使用 notifyAll()来唤醒所有的等待线程。

简而言之:一个线程执行,另一个线程就无限等待,当这个线程执行完毕就唤醒无限等待
线程执行

锁对象调用wait方法进入无限等待时,会释放锁对象,其他线程可以抢占锁对象
线程对象调用sleep方法进入计时等待状态是不会释放锁对象的。

实现等待唤醒机制必须注意:

1.使用锁对象调用wait方法使得线程进入无限等待
2.无限等待线程想要被唤醒,那么必须是其他线程使用锁对象调用notify方法或者notifyAll方法
3.调用wait方法和调用notify方法或notifyAll方法的锁对象必须一致

线程池

为什么需要线程池
线程池可以使得线程重复利用,那么就可以减少频繁创建和销毁消除以及减少系统资源的消耗,提高线程的使用效率和速度

工作原理:
在这里插入图片描述

线程池:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。

线程池的好处:
合理利用线程池能够带来三个好处:

1. 降低资源消耗。减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2. 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
3. 提高线程的可管理性。可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存, 而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

使用线程池

1.创造线程池
2.创建任务对象
3.添加任务到线程池中
4.关闭线程池---基本不操作

线程池:Executor是java里面线程池的顶级接口
真正的线程池接口是java.util.concurrent.ExecutorService
java.util.concurrent.Executors线程工厂类里面提供了一些静态工厂(静态方法),生成一些常用的线程池

Executors类中有个创建线程池的方法如下:

 - public static ExecutorService newFixedThreadPool(int nThreads):返回线程池对象。(创建的是有界线程池,也就是池中的线程个数可以指定最大数量)

使用线程池对象的方法如下:

 - public Future<?> submit(Runnable task):获取线程池中的某一个线程对象,并执行

提示:
Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用。
在线程池中,可以通过在Runnable的实现类中重写的run方法 调用thread .currethre.setname方法来给线程定义名字
打印出来线程名字就不会是默认名

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值