线程和进程
进程是系统进行资源分配和调度的一个独立单位,有独立的地址空间;而线程只是一个进程中的不同执行路径。
进程的资源包括CPU、内存、网络资源,在一个进程内部是共享的,而线程在进程中产生,依附于进程内部,进程内部的线程共享进程中的资源。线程在使用进程中共享的资源时,需要加锁来进行处理。
而每个线程有自己独立的堆栈寄存器、程序计数器和线程控制表(TCB)。
Java中的进程和线程
java语言定义了5中线程状态,这些状态是虚拟机状态,它不反映任何操作系统的线程状态。
JAVA线程间通信:
1)共享内存:读写主内存隐式通信(轮询读取状态),共享对象通信,通过Synchronized,volatile,semaphore等。
2)消息传递:wait和notify,lock锁里的condition
3)管道:PipedOutputStream管道输出流POS , PipedInputStream管道输入流PIS,匹配:pos.connect(pis);
例POS给生产者,PIS给消费者,匹配完成后再线程RUN方法中执行write和read方法,属于单向通信
进程间通信:
1)管道(pipe):具有亲缘关系的进程可以使用,运行一个进程和另一个有共同祖先的进程通信。
2)命名管道(named pipe):允许无亲缘关系的进程之间通信。
3)信号(signal):用于通知接收的进程有某种事情发生,也可进程对自身发送。
4)信号量(semaphore):主要用于进程间以及同一进程不同线程的同步手段,信号量可理解为同步资源数量(3个线程,2个信号量)
5)消息队列(Message):消息的链接表,有足够权限的进程可写入消息,被赋予读权限的进程可读取消息。克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
6)共享内存:使得多个进程可以访问同一块内存空间,可配合信号量使用。
7)内存映射:内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。网络编程。
线程同步的方式:
1)设置临界区(共享内存)
2)设置互斥量(lock锁)
3)设置事件(例如计数栓)
4)设置信号量(AQS共享锁)
死锁产生的四个必要条件(必须同时具备):
1)互斥条件:一个资源每一次只能被一个进程使用
2)请求与保持条件:一个进程因请求资源而阻塞时,对获得的资源保持不放
3)不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
4)循环等待条件:若干进程之间形成一种头尾相接的循环等待关系
避免死锁:
1)合理设置同步区,避免一个线程同时获取多个锁
2)尽量保证一个锁占用一个资源
3)使用tryLock(Timeout)代替内部锁,即加锁顺序,加锁时限
4)对于数据库锁,加解锁必须放在一个数据库连接里