深入浅出带你读懂Java多线程开篇(持续更新)

前置知识

在此之前让我们了解一下操作系统,单处理器,多处理器,进程,线程的概念及它们之间的联系。

在早期的计算机中不包含操作系统,它们从头到尾只执行一个程序,并且这个程序能访问计算机中的所有资源。操作系统的出现使得计算机每次能运行多个程序,并且不同的程序都在单独的进程中运行:操作系统为各个独立执行的进程分配各种资源,包括内存,文件句柄以及安全证书等。如果需要的话,在不同的进程之间可以通过一些粗粒度的通信机制来交换数据,包括:套接字、信号处理器、共享内存、信号量以及文件等。

//未完待续todo add a picture

为了实现更加细粒度的控制,人们发明了线程。线程会共享进程范围内的资源,例如内存句柄和文件句柄,但每个线程都有各自的程序计数器、栈以及局部变量等。

线程也被称为轻量级进程。在大多数现代操作系统中,都是以线程为基本的调度单位,而不是进程。由于同一个进程中的所有线程都将共享进程内的内存地址空间,因此这些线程都能访问相同的变量并在同一个堆上分配对象,这就需要实现一种比在进程间共享数据粒度更细的数据共享机制。如果没有明确的同步机制来协同对共享数据的访问,那么当一个线程正在使用某个变量时,另一个线程可能同时访问这个变量,这就造成不可预料的结果。

//未完待续todo add a picture

多线程的好处

在双处理器系统上,单线程只能使用一半的CPU资源,而在拥有100个处理器的系统上,将有99%的资源无法使用。而多线程程序可以提高处理器资源的利用率。

然而不能说多线程在单处理器系统上毫无作用,它能帮助单处理器系统获得更高的吞吐率。如果一个线程在等待I/O操作完成,另一个线程可以继续运行,使程序能够在I/O阻塞期间继续进行。

线程的安全性问题

线程安全性是非常复杂的,在没有充分同步的情况下,多个线程中的操作执行顺序是不可预测的。

public class UnsafeSequence {
    private int value;
    //对value实行加一操作
    public int getNext() {
        return value++;
    }
}

虽然递增运算value++看上去是个单个操作,但事实上它包含三个独立的操作:读取value,将value加1,并将计算结果写入value。由于运行时可能将多个线程之间的操作交替执行,因此这两个线程可能同时执行读操作,结果就是,在不同线程的调用中返回了相同的数值。

ymEC8S.png

通过将getNext()修改为一个同步方法,可以修复UnsafeSequence中的错误。

public class Sequence {
    private int Value;
    
    public synchroized int getNext() {
        return Value++;
    }
}

如果没有同步,那么无论编译器、硬件还是运行时,都可以随意安排操作的执行时间和顺序,例如对寄存器或者处理器中的变量进行缓存,而这些被缓存的变量对于其他线程来说是暂时不可见的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值