【JUC-1】java多线程线程基础知识

这篇具有很好参考价值的文章主要介绍了【JUC-1】java多线程线程基础知识。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

线程创建方式

  1. 继承Thread类.
  2. 实现Runable接口.
  3. 实现Callable接口.

Runable/Callable接口的实现, 都是重写其中的run/call方法, 实现任务逻辑, 再由线程执行器(可以是Thread类,也可以是线程池)并发执行run/call的逻辑.

而Thread类中的包含start方法, 可以控制线程启动,执行任务.

线程上下文切换(Thread Context Switch)

当发生线程上下文切换时, 操作系统会保存当前线程状态, 并且恢复另一个线程的运行. java中程序计数器就会记录当前线程下一个执行指令的地址, 当线程切换时, 依据这个地址继续执行程序. 这个程序计数器是线程私有的.

线程状态

NEW: 线程创建, 还没与操作系统中的线程关联

注意操作系统的线程状态定义与java中有所不同. 操作系统中的block是指, 调用了阻塞API比如IO读取文件操作, 操作系统的线程状态就会进入阻塞状态.

操作系统的可运行状态是指线程还没有获得cpu时间片

现成状态转换图:

【JUC-1】java多线程线程基础知识,java并发编程,java,JUC,多线程

Thread类中常见API

方法名 说明 备注
start() void 启动一个线程,现成执行run方法中逻辑 方法执行后, 新创建线程为就绪态
join() void 阻塞等待当前线程执行结束
join(long n) void 阻塞等待当前线程执行结束, 最多等待n毫秒
getId() long 获取long类型线程ID
getName() String 获取线程名称
getPriority() int 获取线程优先级 1 - 10 , 10优先级最高
setPriority(int i) 设置线程优先级 最大 10, 最小1, 超出抛异常
getState() State 获取线程状态枚举值 State:{NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED}
isInterrupted() boolean 判断现成是否被中断
interrupt() void 打断线程 sleep, waite, join时的线程, 如果调用interrupt方法会抛异常:InterruptedException, 并且清除中断标记(isInterrupted方法返回false), 如果是运行中的线程, 被打断, 会设置打断标记(isInterrupted方法返回false)
isAlive() boolean 判断现成是否存活 即未运行完毕的线程
sleep(long n) 线程休眠,进入time_waiting状态
yield() 线程让出时间片

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);
        }
    } else {
        // 设置超时时间,加入等待
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

join案例

public class Test7 {
    private static final Object obj = new Object();

    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (obj) {
                    try {
                        System.out.println("执行逻辑");
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        
        t.start();
        t.join();
    }
}

在上面的案例代码中, t.join()方法会让main方法进入wait等待. 阻塞的是main方法. 当t1线程执行完run方法逻辑后. JVM底层就会调用notify方法, 唤醒持有t1锁对象的线程.(join()方法是被synchonized修饰的, 锁对象就是线程对象)

JVM唤醒join源码

// 位于/hotspot/src/share/vm/runtime/thread.cpp中
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
    // ...

    // Notify waiters on thread object. This has to be done after exit() is called
    // on the thread (if the thread is the last thread in a daemon ThreadGroup the
    // group should have the destroyed bit set before waiters are notified).
    // 有一个贼不起眼的一行代码,就是这行
    ensure_join(this);

    // ...
}


static void ensure_join(JavaThread* thread) {
    // We do not need to grap the Threads_lock, since we are operating on ourself.
    Handle threadObj(thread, thread->threadObj());
    assert(threadObj.not_null(), "java thread object must exist");
    ObjectLocker lock(threadObj, thread);
    // Ignore pending exception (ThreadDeath), since we are exiting anyway
    thread->clear_pending_exception();
    // Thread is exiting. So set thread_status field in  java.lang.Thread class to TERMINATED.
    java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
    // Clear the native thread instance - this makes isAlive return false and allows the join()
    // to complete once we've done the notify_all below
    java_lang_Thread::set_thread(threadObj(), NULL);

    // 同志们看到了没,别的不用看,就看这一句
    // thread就是当前线程,是啥?就是刚才例子中说的t线程啊。
    lock.notify_all(thread);

    // Ignore pending exception (ThreadDeath), since we are exiting anyway
    thread->clear_pending_exception();
}

守护线程

Java提供了两种线程:守护线程用户线程

当所有非守护线程结束时,程序就会终止,而不管守护线程是否还在运行。守护线程通常用于执行一些后台任务或服务,例如垃圾回收器(Garbage Collector)线程就是一个守护线程。

最主要的区别就是, 系统中某一时刻, 存在守护线程正在运行, 而没有用户线程运行. 那么JVM就会结束运行.文章来源地址https://www.toymoban.com/news/detail-516200.html

到了这里,关于【JUC-1】java多线程线程基础知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 复习并发编程的基础知识(一)

    目录 进程和线程 并发和并行  如何创建一个线程? 1,继承Thread类  2,实现Runnable接口          3. Callable接口 线程Thread类的一些重要方法  守护线程: 时间长了,并发编程的基础知识总忘,来记录一下: 进程和线程 进程:资源分配的最小单元,什么是资源?CPU,内存,网

    2024年02月08日
    浏览(59)
  • 3.多线程之JUC并发编程0

    1.学习方法 java1.8才有juc 面试高频问 源码+官方文档 //怎么用多线程,如果是没有返回结果的就单独开一条线程,或者使用线程池,如果有返回值的就用callable 2.什么是juc 三个包 java.util.concurrent java.util.concurrent.atomic java.util.concurrent.locks 介绍 Callable性能比Runnable高,并且Runnable没有返

    2024年02月08日
    浏览(52)
  • 5.多线程之JUC并发编程2

    1.CompletableFuture异步回调 像ajax,未来再得到执行结果,想服务器不分先后顺序执行,可以用异步回调 2.JMM 面试:对 Volatile的理解 答: Volatile是jvm通过轻量级的同步机制,比sychronized更轻 1.保证可见性 2.不保证原子性 3.禁止指令重排 什么是JMM? 答:java内存模型,是一种规定,不存在的东西

    2024年02月08日
    浏览(41)
  • JUC并发编程学习笔记(十)线程池(重点)

    线程池:三大方法、七大参数、四种拒绝策略 池化技术 程序的运行,本质:占用系统的资源!优化资源的使用!- 池化技术(线程池、连接池、对象池......);创建和销毁十分消耗资源 池化技术:事先准备好一些资源,有人要用就拿,拿完用完还给我。 线程池的好处: 1、

    2024年02月06日
    浏览(46)
  • JUC并发编程学习笔记(一)认知进程和线程

    进程 一个程序,如QQ.exe,是程序的集合 一个进程往往可以包含多个线程,至少包含一个 java默认有两个线程,GC垃圾回收线程和Main线程 线程:一个进程中的各个功能 java无法真正的开启线程,因为java是运行在虚拟机上的,所以只能通过C++,通过native本地方法调用C++开启线程

    2024年02月06日
    浏览(55)
  • JUC并发编程-集合不安全情况以及Callable线程创建方式

    1)List 不安全 ArrayList 在并发情况下是不安全的 解决方案 : 1.Vector 2.Collections.synchonizedList() 3. CopyOnWriteArrayList 核心思想 是,如果有 多个调用者(Callers)同时要求相同的资源 (如内存或者是磁盘上的数据存储),他们 会共同获取相同的指针指向相同的资源 , 直到某个调用者

    2024年01月23日
    浏览(49)
  • java基础之线程知识点

    操作系统(OS)中并发(同时)执行的多个程序任务 宏观并行,微观串行 在一个时间段内,CPU会将时间段划分为若干个时间片,一个时间片是能被一个程序拥有,且只有拥有时间片的程序才能执行自身内容,所以当时间片的划分足够细小,交替频率足够快,就会形成并行的假象,时间上仍然是

    2024年02月01日
    浏览(50)
  • JUC 高并发编程基础篇

    • 1、什么是 JUC • 2、Lock 接口 • 3、线程间通信 • 4、集合的线程安全 • 5、多线程锁 • 6、Callable 接口 • 7、JUC 三大辅助类: CountDownLatch CyclicBarrier Semaphore • 8、读写锁: ReentrantReadWriteLock • 9、阻塞队列 • 10、ThreadPool 线程池 • 11、Fork/Join 框架 • 12、CompletableFuture 1 什么

    2024年02月07日
    浏览(53)
  • Java面试_并发编程_线程基础

    进程是正在运行程序的实例, 进程中包含了线程, 每个线程执行不同的任务 不同的进程使用不同的内存空间, 在当前进程下的所有线程可以共享内存空间 线程更轻量, 线程上下文切换成本一般上要比进程上下文切换低(上下文切换指的是从一个线程切换到另一个线程) 并发是单个

    2024年02月07日
    浏览(54)
  • JUC并发编程-线程和进程、Synchronized 和 Lock、生产者和消费者问题

    源码 + 官方文档 面试高频问! java.util 工具包、包、分类 业务:普通的线程代码 Thread Runnable Runnable 没有返回值、效率相比入 Callable 相对较低! 线程、进程,如果不能使用一句话说出来的技术,不扎实! 进程:一个程序,QQ.exe Music.exe 程序的集合; 一个进程往往可以包含多

    2024年01月20日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包