线程---关于死锁,进程和线程,多进程与多线程,synchronized与ReentrantLock的区别

怎么理解系统的进程和线程??

进程:
进程是系统划分资源(I/O资源[磁盘,文件],CPU资源,内存资源)的基本单位,进程本身不执行任何的指令;
每一个进程的创建,都伴随着一个主线程的创建,线程才是负责执行指令的,也就是说Linux系统调用的基本执行单元,就是线程(main线程 线程 = 线程栈(线程函数 main函数)),自己创建的线程,也是需要匹配一个线程的入口函数的,就是run函数;

线程:
线程是执行指令的单元,运行在一个进程的空间里面的,线程没有自己独立的用户空间。必须共享一个进程的用户空间,每一个线程都有自己独立的栈空间,他们共享一个进程的堆空间和.bss .data .text段;

为什么要写多线程或者多进程程序?这两者之间不同的地方??? 如何区分?

因为现在的PC机或者服务器都是多核的CPU,一次可以并发执行多个线程,如果程序中还使用 单进程或者单线程,对CPU的资源是一种浪费,没有有效的利益CPU的资源。

一般编写多线程或者多进程的程序,线程或者进程的数量是和当前CPU的核心数量是一致的( 比如我看过的Apache mina或者netty网络库,就是这样做的),这样能发挥CPU多核的效率, 能够让多个进程或者线程并发执行。

由于进程占用的资源比较大,而线程占用的资源比较少,所有在多线程和多进程程序中,随着CPU的调度,进程的上下文切换所花费的时间效率远远高于线程,因为线程比较轻量,占用资源少,所以上下文切换快,多进程程序,各进程之间进行数据共享,进程通信,进程互斥操作,非常复杂,不易实现;而线程 由于是共享进程空间的,所以共享堆和.bss .data.text;因此线程之间共享数据非常方便,通信也方便(wait/notify),线程互斥(锁)都很方便。

所以大多数都使用多线程程序。

操作系统进程间通信的方式:匿名管道,命名管道,消息队列,共享内存,信号量,套接字。

你见过哪些死锁的问题??

  1. 多个线程,都在获取多个锁资源,但是获取锁资源的顺序不同(可能会死锁)

    ----》多个线程获取锁资源,加锁解锁的顺序必须保持一致;

  2. 哲学家就餐问题:

    每一个哲学家(相当于一个线程)占用了一个筷子资源,因为得不到另外一支筷子资源,造成几个线程相互等待对方释放资源,因为没有线程释放资源(筷子),造成整个系统死锁;

  3. 多线程的生产者消费者模型:

    多线程程序,

线程间互斥:synchronized 与 ReentrantLock的区别:

(1)synchronized (java对象都有一个对象头8个字节4字节+方法表的地址)

ReentrantLock java.util.concurrent.并发包JDK1.5)

synchronized效率太低,锁太重;JDK1.6开始,对synchronized做了很大优化,可以实现轻量级锁,偏向锁,自旋锁;

(2)synchronized是java的关键字,语言级别实现线程互斥;

ReentrantLock只是并发包concurrent包而提供的一个类,通过相应的方法调用 ,实现线程互斥;

(3)synchronized的加锁解锁是自动进行的,开发者不需要关心;

ReentrantLock必须手动调用lock和unlock方法进行加锁解锁操作,使用ReentrantLock一定要括在try finally块里面,在finally块中调用unlock方法释放并发锁,防止死锁发生;

(4)synchronized线程互斥,对读读,读写,写写都会进行互斥操作;

但是并发包里面提供了专门的ReentrantReadWriteLock这个读写锁;使得临界区代码段如果是读读操作,可以并发执行,但是读写和读读还是互斥执行的。

线程间的通信方式:共享内存和消息传递。

(1)volatile;(实现共享内存,多个线程同时监听一个变量)

(2)Object.wait(), notify(),notifyAll():一般与synchronized连用,wait释放锁,notify获取锁;

(3)CountDownLatch类:java.util.concurrent包下的;

(4)ReentrantLock + Condition;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章