JAVA多线程:Thread类和他们的朋友们

Thread类

Thread类在java.lang中,实现runable接口。由于java不支持多线程,所以该类至少需要以下功能:

  • 作为用户实现的线程类的父类
  • 将用户实现的实现runable接口的类的对象转换为Thread对象
  • 提供当前代码访问系统线程信息的能力
  • 控制当前线程状态

我们都知道,启动线程执行并非是thread.run而是thread.start,这是因为start中调用了

    private native void start0();

从而真正开启了线程的执行。每一个线程都属于一个ThreadGroup,可以通过TreadGroup来操作多个线程。

多线程框架

这里写图片描述

上图中的红线代表相关的关系。
这个极为丑陋的图希望大家能对java构建多线程又一个总体的认识,至少要看懂以下三点:

  • Java多线程的根是Thread类的native start0方法,任何实现都不可能绕开这一点。为了调用这个方法,最原生的做法就是继承thread类,或者实现runable接口,然后用runable对象初始化一个thread对象。在底层,start0方法会使用操作系统fork一个线程出来。具体到linux,一个JVM线程对应一个轻量级进程,而一个轻量级进程对应一个特定的内核线程。这种方式的好处是直接调用内核来调度线程,但是也有缺点,线程执行时需要频繁切换用户态和内核态。

  • Java最原始的Runable接口和JUC中Callable接口的地位是平行的,区别在于一个run方法有返回值,而另一个没有。FutureTask这个类非常重要。负责把callable对象转化成一个runable对象。

  • Executors是Executors框架的核心,负责生成Executor对象,这个对象可以是一个线程,也可以是线程池(ThreadPoolExecutor)。在生成线程池的ThreadPoolExecutor对象时,需要传入一个ThreadFactory对象,这个对象利用Thread类的功能产生新的线程。

工作过程

Java线程池会将提交的任务先置于工作队列中,在从工作队列中获取(SynchronousQueue直接由生产者提交给工作线程)。那么工作队列就有两种实现策略:无界队列和有界队列。无界队列不存在饱和的问题,但是其问题是当请求持续高负载的话,任务会无脑的加入工作队列,那么很可能导致内存等资源溢出或者耗尽。而有界队列不会带来高负载导致的内存耗尽的问题,但是有引发工作队列已满情况下,新提交的任务如何管理的难题,这就是线程池工作队列饱和策略要解决的问题。
饱和策略分为:Abort 策略, CallerRuns 策略,Discard策略,DiscardOlds策略。

  • Abort 策略 抛出异常,这是默认策略
  • CallerRuns 策略,将这个工作交给放工作进队列的线程来做
  • Discard策略,直接丢弃当前要添加的工作。
  • DiscardOlds 将队列头(最早被提交但没有开始执行的工作)的工作删除,向队列中添加当前工作

静态方法

  • currentThread:获取当前代码的执行线程,由JVM提供实现
public static native Thread currentThread();
  • sleep方法:让当前线程进入阻塞状态
public static void sleep(long millis, int nanos)
  • yield方法:让当前线程让出cpu,进入就绪状态
public static native void yield();

对象方法:

  • start()方法
    开始运行线程。系统会自动执行线程中的run方法。注意,直接调用thread对象的类方法是启动不了线程的

  • getId()
    获取线程的唯一标志

  • isAlive()
    判断线程是否处于活动状态

  • join()
    当前线程等待该线程结束

  • getName和setName
    用来得到或者设置线程名称。

  • getPriority和setPriority
    用来获取和设置线程优先级。线程的默认优先级和启动该线程的线程相同。注意,JVM不保证线程优先级机制一定有效,

  • setDaemon和isDaemon
    用来设置线程是否成为守护线程和判断线程是否是守护线程。

守护线程和用户线程的区别在于:守护线程依赖于创建它的线程,而用户线程则不依赖。举个简单的例子:如果在main线程中创建了一个守护线程,当main方法运行完毕之后,守护线程也会随着消亡。而用户线程则不会,用户线程会一直运行直到其运行完毕。在JVM中,像垃圾收集器线程就是守护线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值