本文共 2336 字,大约阅读时间需要 7 分钟。
首先来介绍下进程的同步与互斥
进程的同步:一个进程的执行,依赖于另一个进程的运行的消息, 消息到达才能继续执行。我们把异步环境下的一组并发进程因直接制约而互相发送消息、进行互相合作、互相等待,使得各进程按一定的顺序执行的过程称为进程间的同步。在多道程序环境下,进程是并发执行的,不同进程之间存在着不同的相互制约关系
进程的互斥:两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥,也就是说,一个进程正在访问临界资源,另一个要访问该资源的进程必须等待。
概念比较抽象,举个例子,经典的生产者和消费者问题
多个生产者共同生成产品,它们将产品放入仓库(临界区),多个消费者取出产品,对产品进行消费。这里的多个生产者,某一时刻只允许一个生产者将产品放入临界区,多个生产者之间是互斥关系。生产者生产了产品并放入仓库, 消费者才能取出产品进行消费,这里的生产者和消费者是同步关系。
同步与互斥不是一对反义词,互斥的反义词应该是共享。
同步反应的是一种协作关系。
如果做过LinuxC系统编程,真正写过PV操作、信号量、互斥锁等相关开发,相信你比较清楚以上概念了。Java中的同步以及同步的实现封装了,我个人感觉实现的并不好。
多个线程执行的不确定性引起执行结果的不稳定
多个线程对数据的共享,会造成操作的不完整性,会破坏数据。
多线程处理缓冲区的消息时,存在重复处理和错误处理问题,比如重复处理消息100, 错误处理了消息0或-1等。
//ProcessMessageTest.javapackage com.ylaihui.thread;class ProcessMessage implements Runnable{ private int message = 100; @Override public void run() { while(true) { if(message > 0) { System.out.println("process message: " + message); message--; }else break; } }}public class ProcessMessageTest { public static void main(String[] args) { ProcessMessage p = new ProcessMessage(); Thread t1 = new Thread(p); Thread t2 = new Thread(p); Thread t3 = new Thread(p); t1.start(); t2.start(); t3.start(); }}
synchronized(同步监视器){//需要被同步的代码}
说明:
1.操作共享数据的代码,即为需要被同步的代码
2.共享数据:多个线程共同操作的变量
3.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁,但是多个线程必须要共用同一把锁。
通过实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。
使用继承Thread创建多线程的方式,可以使用继承类的Xxx.class方式充当同步监视器
代码示例: 多线程同时处理100条消息
//ThreadSynchronizedBlock.javapackage com.ylaihui.thread;class ProcessMessage1 implements Runnable{ private int message = 100; Object obj = new Object(); @Override public void run() {// synchronized(obj){ synchronized(this){ while(true){ if(message > 0){ System.out.println("process message: "+ message); message--; }else break; } } }}public class ThreadSynchronizedBlock { public static void main(String[] args) { ProcessMessage1 p = new ProcessMessage1(); Thread t1 = new Thread(p); Thread t2 = new Thread(p); Thread t3 = new Thread(p); t1.start(); t2.start(); t3.start(); }}
转载地址:http://ltuhf.baihongyu.com/