线程学习(一)之线程基础、线程之间的共享和协作(一)

本文深入探讨了CPU核心数、线程数的关系,时间片轮转机制,进程与线程的区别,以及并行和并发的概念。介绍了Java线程的创建方式、线程安全停止的方法,线程的优先级、守护线程的概念,以及synchronized内置锁和volatile关键字的使用,帮助读者全面理解多线程编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础概念

CPU核心数和线程数的关系

核心数:线程数 = 1:1 ;超线程技术后变成1:2

CPU时间片轮转机制

时间片轮转法(Round-Robin,RR)主要用于分时系统中的进程调度。为了实现轮转调度,系统把所有就绪进程按先入先出的原则排成一个队列。新来的进程加到就绪队列末尾。每当执行进程调度时,进程调度程序总是选出就绪队列的队首进程,让它在 CPU 上运行一个时间片的时间。时间片是一个小的时间单位,通常为 10~100ms 数量级。当进程用完分给它的时间片后,系统的计时器发出时钟中断,调度程序便停止该进程的运行,把它放入就绪队列的末尾;然后,把 CPU 分给就绪队列的队首进程,同样也让它运行一个时间片,如此往复。
链接:https://hacpai.com/article/1541479518505

什么是进程和线程

进程

程序运行资源分配的最小单位,进程内部有多个线程,这些线程会共享这个进程的资源。进程与进程之间相互独立。

线程

CPU调度的最小单位。线程不能独立运行,必须依附进程,它本身不能拥有系统资源的。进程获取资源,线程去使用。

并行和并发

并行:同一时刻,可以处理事情的能力。与CPU的核数有关
并发:与单位时间相关,在单位时间内可以处理事情的能力。与CPU的核数以及系统切割的时间片长度有关。

高并发编程的意义,好处和注意事项

1. 可以充分利用CPU的资源,加快响应用户的时间
2. 可以使代码模块化,异步化
注意事项:共享资源,存在冲突,控制不好存在死锁现象。操作太多的线程容易内存溢出和内存消耗殆尽,死机。

认识java里面的线程

Java里的程序天生就是多线程的,那么有几种新启线程的方式?
类Thread、接口Runnable、接口Callable

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

public class OnlyMain {
    public static void main(String[] args) {
        //虚拟机线程管理的接口
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
        for (ThreadInfo threadInfo:threadInfos) {
            System.out.println("["+threadInfo.getThreadId()+"]"+"  "+threadInfo.getThreadName());
        }
    }
}
控制台
[1]  main
[2]  Reference Handler
[3]  Finalizer
[4]  Signal Dispatcher
[5]  Attach Listener
最基本的main方法都有五个线程
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
多线程类的使用
public class NewThread {
    //拓展自Thread类

    //实现Runnable接口
    private static class UseRun implements Runnable{

        @Override
        public void run() {
            System.out.println("Runnable!!");
        }
    }

    //实现Callable接口,允许有返回值
    private static class UseCall implements Callable{

        @Override
        public String call() throws Exception {
            System.out.println("Callable!!!");
            return "CallResult";
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        UseRun useRun = new UseRun();
        new Thread(useRun).start();
        UseCall useCall = new UseCall();
        FutureTask<String> futureTask = new FutureTask<>(useCall);
        new Thread(futureTask).start();
        System.out.println(futureTask.get());
    }
}

怎么让java里的线程安全停止

线程的停止
1.自然执行完
2.抛出异常
stop(),resume(),suspend(),方法停止线程,不会释放资源
Java线程是协作式
interrupt()中断一个线程,并不是强制关闭这个线程,打个招呼,中断标志位置为true
isInterrupted()判断当前线程是否处于中断状态
static方法interrupted()判断当前线程是否处于中断状态,中断标志位改为false
方法会抛出InterruptedException,线程得中断标志会被复位成false,需要我们在catch里面再次中断

对Java里的线程多一点了解

线程的优先级
1-10 缺省为5
守护线程
与主线程同生共死。主线程结束,守护线程停止。

线程间的共享

synchronized内置锁

用处:在多线程编程中,线程安全问题是一个最为关键的问题,其核心概念就在于正确性,即当多个线程访问某一共享、可变数据时,始终都不会导致数据破坏以及其他不该出现的结果。而所有的并发模式在解决这个问题时,采用的方案都是序列化访问临界资源 。在 Java 中,提供了两种方式来实现同步互斥访问:synchronized 和 Lock。本文针对 synchronized 内置锁 详细讨论了其在 Java 并发 中的应用,包括它的具体使用场景(同步方法、同步代码块、实例对象锁 和 Class 对象锁)、可重入性 和 注意事项。

对象锁

对象锁:synchronized定义在方法上或者方法的代码模块内,锁的是new出来的对象。不同对象之间可以同时运行

类锁

类锁:synchronized定义在静态方法上面,锁的是Class,只要是这个类的对象都会生效。
类锁和对象锁是可以同时运行的。

注意

类锁和对象锁都是不存在的,只是抽象出来的概念,便于我们理解java的synchronized内置锁机制

volatile

volatile关键字线程不安全,只能保证可见性,不能保证原子性
ThreadLocal 多用键值对的方式来存储,每一个线程都有自己的一个副本,进行操作是都是操作自己的副本,所以不会产生线程之间的冲突。由于每个ThreadLocal 都有自己的副本,当存储的值很大时,将会很占内存。所以建议存储小,少的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值