JAVA学习->多线程

一、什么是多线程?

        相信大家对操作系统的多任务很熟悉,即在同一时刻运行多个程序的能力。例如,在发QQ信息时可以播放音乐。而且,现在的计算机几乎都是多个CPU的计算机,但是,并发执行的进程数目并不是由CPU的数目制约的,操作系统将CPU的时间片分配给每一个进程,由于计算机极快的运行速度,才会给人同时并发进行的错觉。

        多线程程序在较低层次上扩展了多任务的概念:一个程序同时执行多个任务。通常,每一个任务称为一个线程。可以同时运行一个以上线程的程序称为多线程程序。


二、多线程和多进程的区别

        本质上的区别在于每个进程都有自己的一整套变量,而线程是数据共享的。所以,数据变量的共享是的线程之间的通信比进程之间的通信更有效、更容易。此外,在操作系统中,线程与进程相比,线程更”轻量级”,创建和撤销一个线程比启动一个新进程开销要小的多。具体比较如下:

        1、进程是资源分配的最小单位,线程是CPU调度的最小单位。

         2、从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

         3、线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。

        4、进程之间传递数据只能是通过通讯的方式,即费时又不方便。线程时间数据大部分共享(线程函数内部不共享),快捷方便。但是数据同步需要锁对于static变量尤其注意


三、线程安全及可重入

1、线程安全

       概念比较直观。一般说来,一个函数被称为线程安全的,当且仅当被多个并发线程反复调用时,它会一直产生正确的结果。

线程安全的条件:
       要确保函数线程安全,主要需要考虑的是线程之间的共享变量。属于同一进程的不同线程会共享进程内存空间中的全局区和堆,而私有的线程空间则主要包括栈和寄 存器。因此,对于同一进程的不同线程来说,每个线程的局部变量都是私有的,而全局变量、局部静态变量、分配于堆的变量都是共享的。在对这些共享变量进行访 问时,如果要保证线程安全,则必须通过加锁的方式。

2、可重入

       所谓“重入”,常见的情况是,程序执行到某个函数f()时,收到信号,于是暂停目前正在执行的函数,转到信号处理函数,而这个信号处理函数的执行过程中,又恰恰也会进入到刚刚执行的函数f(),这样便发生了所谓的重 入。此时如果f()能够正确的运行,而且处理完成后,之前暂停的f()也能够正确运行,则说明它是可重入的。

要确保函数可重入,需满足一下几个条件:
        1、不在函数内部使用静态或全局数据 
        2、不返回静态或全局数据,所有数据都由函数的调用者提供。 
        3、使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
        4、不调用不可重入函数。

        可重入与线程安全并不等同,一般说来,可重入的函数一定是线程安全的,但反过来不一定成立。

        如果我们的线程函数不是线程安全的,那在多线程调用的情况下,可能导致的后果是显而易见的——共享变量的值由于不同线程的访问,可能发生不可预料的变化,进而导致程序的错误,甚至崩溃。

猜你喜欢

转载自blog.csdn.net/wuyileiju__/article/details/80576483