行业资讯 2025年08月6日
0 收藏 0 点赞 670 浏览 3693 个字
摘要 :

文章目录 Thread 常用构造方法 常用方法 Runnable ThreadLocal 成员变量 构造方法 方法 先设值 再取值  总结 本文主要对Java多线程种Thread、Runnable、ThreadLoca……




  • Thread
    • 常用构造方法
    • 常用方法
  • Runnable
  • ThreadLocal
    • 成员变量
    • 构造方法
    • 方法
    • 先设值
    • 再取值
  •  总结

本文主要对Java多线程种Thread、Runnable、ThreadLocal类进行源码解读分析。我们一起来看下吧。

Thread

public class Thread implements Runnable

1、 线程是程序中的执行线程Java虚拟机允许应用程序并发地运行多个执行线程;

2、 每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程;

3、 创建新执行线程有两种方法一种方法是将类声明为Thread的子类该子类应重写Thread类的run方法newThread().start()另一种方法是声明实现Runnable接口的类该类然后实现run方法newThread(Runnable实现类实例).start();

推荐使用声明实现 Runnable 接口的类。符合面向接口编程思想。

常用构造方法

Thread() 分配新的 Thread 对象。
Thread(Runnable target) 分配新的 Thread 对象。
Thread(Runnable target, String name) 分配新的 Thread 对象。
Thread(String name) 分配新的 Thread 对象。

常用方法

Thread currentThread():返回对当前正在执行的线程对象的引用。

public static native Thread currentThread()//native方法

void sleep(long millis) :在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。不释放锁。

public static native void sleep(long millis) throws InterruptedException;//native方法

void yield():暂停当前正在执行的线程对象,并执行其他线程,且只能让同优先级的线程有执行的机会。不释放锁。

public static native void yield();

void join(long millis) :等待该线程终止的时间最长为 millis 毫秒。join(0)等价于join()。

public final synchronized void join(long millis) 
    throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
            throw new IllegalArgumentException(\"timeout value is negative\");
    }

    if (millis == 0) {
        while (isAlive()) {
        wait(0);//Object.wait方法,native方法
        }
    } else {
        while (isAlive()) {
        long delay = millis - now;
        if (delay <= 0) {
            break;
        }
        wait(delay);
        now = System.currentTimeMillis() - base;
        }
    }
}

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

public synchronized void start() {
    if (threadStatus != 0 || this != me)
        throw new IllegalThreadStateException();
    group.add(this);
    start0();
    if (stopBeforeStart) {
        stop0(throwableFromStop);
    }
}

void interrupt():中断线程。

public void interrupt() {
    if (this != Thread.currentThread())
        checkAccess();

    synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
        interrupt0();        // Just to set the interrupt flag
        b.interrupt();
        return;
        }
    }
    interrupt0();
}

destroy() 、resume()、suspend() 、stop() 已过时且不安全,因此不作介绍。

Runnable

public interface Runnable

1、接口实现类类必须定义一个称为run的无参数方法;

2、设计该接口的目的是为希望在活动时执行代码的对象提供一个公共协议;

3、 Runnable为非Thread子类的类提供了一种激活方式通过实例化某个Thread实例并将自身作为运行目标,就可以运行实现Runnable的类而无需创建Thread的子类大多数情况下,如果只想重写run()方法,而不重写其他Thread方法,那么应使用Runnable接口这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类创建子类;

public interface Runnable {
    /**
     *  使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法。
     *
     * @see java.lang.Thread#run()
     */
    public abstract void run();
}

ThreadLocal

public class ThreadLocal

1、 该类提供了线程局部(thread-local)变量这些变量不同于它们的普通对应物,因为访问某个变量(通过其get或set方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本;

2、ThreadLocal实例通常是类中的privatestatic字段,它们希望将状态与某一个线程(例如,用户ID或事务ID)相关联;

成员变量

/**
 * 本地线程哈希码
 */
private final int threadLocalHashCode = nextHashCode();

/**
 * 下一个本地线程的哈希码
 */
private static AtomicInteger nextHashCode = 
new AtomicInteger();

/**
 * 哈希码增量
 */
private static final int HASH_INCREMENT = 0x61c88647;

/**
 * 返回下一个哈希码:nextHashCode + HASH_INCREMENT
 */
private static int nextHashCode() {
    return nextHashCode.getAndAdd(HASH_INCREMENT); 
}

构造方法

/**
 * 创建一个线程本地变量。
 */
public ThreadLocal() {
}

方法

T get() 返回此线程局部变量的当前线程副本中的值。
void set(T value) 将此线程局部变量的当前线程副本中的值设置为指定值。

大部分子类不需要重写此方法,它们只依靠 initialValue() 方法来设置线程局部变量的值。

void remove() 移除此线程局部变量当前线程的值。如果此线程局部变量随后被当前线程 读取,

且这期间当前线程没有 设置其值,则将调用其 initialValue() 方法重新初始化其值。

这将导致在当前线程多次调用 initialValue 方法。

T initialValue() 返回此线程局部变量的当前线程的“初始值”。

ThreadLocal由其内部类ThreadLocalMap实现的。每个ThreadLocal维护一个ThreadLocalMap实例,key为ThreadLocal实例本身,value是真正需要存储的Object。

先设值

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}
void createMap(Thread t, T firstValue) {
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}

再取值

public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);//获取当前线程ThreadLocalMap
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);//找到对应map
        if (e != null)
            return (T)e.value;//返回对应值
    }
    return setInitialValue();//没有值,进行初始化
}

ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

 总结

以上就是Java多线程:Thread、Runnable、ThreadLocal源码解读的全部内容!

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/9693.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号