Thread基本原理

        线程是操作系统能够进行运算的最小单元,是独立调度和分派的基本单元,是进程中的实际运作的单元。一个进程可以有并发执行多个线程,每条线程并发执行不同的任务;同一个进程中的多个线程可以共享该进程中的全部系统资源,例如:虚拟地址空间,文件描述符和信号处理等等。每个线程都有自己的调用栈,寄存器环境,本地存储。

线程实际上只有一点必不可少的,能够保证独立运行的资源。线程的实体包括程序、数据、TCB(Thread Control Block 线程控制块)。

TCB包括:线程状态、线程不运行时被保存的现场资源、一组执行堆栈、存放每个线程的局部变量主存区、访问同一个进程中的主存和其他资源。

线程与进程之间的区别如下:

1、地址空间和其他资源:进程之间相互独立间,统一进程中的各个线程间资源共享,进程内的线程对其他的进程不可见。

2、通信:进程间通信IPC,线程间可以直接读写进程数据段来进行通信--需要进程同步和互斥来协助,以保证数据的一致性。

3、调度和切换:由于线程比进程更小,基本上不拥有系统资源,因此在调度的过程中付出的开销要小得多,线程上下文切换比进程上下文切换要快得多。

4、进程是分配资源的基本单位,线程是独立运行和独立调度的基本单位。

线程的并发安全性:

多线程:多线程中有两个概念就是并行和串行,并行就是同一时刻执行的任务,在时间上是重叠的。串行就是对于单个线程执行多个任务来说,多个任务必须是按照一定的顺序执行的,只有上一个任务完成之后才能执行下一个任务,在时间上是不重叠的。

线程安全:

在多线程并发执行的过程中访问同一数据时,程序是否能继续按照预期的效果去执行,保证数据的一致性,安全性,可见性。

public class ThreadDemo1 {
    private int count ;
    private void add(){
        count ++;
    }

    private void runThread(){
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    add();
                    System.out.println(Thread.currentThread().getName()+":" +count);
                }
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    add();
                    System.out.println(Thread.currentThread().getName()+":" +count);
                }
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    add();
                    System.out.println(Thread.currentThread().getName()+":" +count);
                }
            }
        }.start();
    }

    public static void main(String[] args) {
        ThreadDemo1 threadDemo1 = new ThreadDemo1();
        threadDemo1.runThread();
    }
}

期望值为:30000,真正的执行结果:

Thread-2:29995
Thread-2:29996
Thread-2:29997
Thread-2:29998
Thread-2:29999

Process finished with exit code 0

线程的并发就需要保证共享数据的原子性、一致性、可见性。

原子性:对共享的内存中的数据操作时要么全部执行,要么不执行,并且在执行的过程中不能被其他的外界因素打断。

可见性:多线程操作共享内存的时候,执行的结果能够及时的同步到共享内存,确保这个结果对其他线程是可见的。

有序性:程序的执行顺序按照代码的顺序执行,在单线程的环境下,程序的执行都是有序的,但是在多线程的环境下,JMM为了性能的优化,编译器和处理器会对指令进行重排序,程序的执行会变得无序。

各个线程在执行任务的时候是如何操作数据以及存储数据?

由上图可以看出来,线程在对共享内存数据进行操作的时候,需要将操作的变量拷贝到线程工作内存中(读操作),在进行完成一系列的业务逻辑操作之后,需要将更改的变量重写存储到主内存中。然而在线程AB在再将变量存入到主内存的时候,就会出现数据安全性的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值