为了在线程间进行可靠的通信,也为了互斥访问,同步是必要的。

原创 2015年07月06日 16:36:02

为了在线程间进行可靠的通信,也为了互斥访问,同步是必要的。
例子程序:

public class ThreadCommunication 
{
    private static boolean stopRequested = false;

    public static void main(String[] args) throws Exception
    {
        Thread backgroundThread = new Thread(new Runnable(){
            public void run()
            {
                int i=0;
                while(!stopRequested)
                {
                    i++;
                }
            }
        });

        backgroundThread.start();
        Thread.sleep(1000);
        stopRequested = true;
    }
}

你可能期待这个程序运行一秒钟左右,之后主线程将stopRequested 设置为true,致使后台线程循环中止,但在笔者的机器上,后台程序并没有在主线程将stopRequested 设为true后终止,while循环无限的循环了下去。
问题在于:没有同步,就不能保证后台线程何时“看到”主线程对stopRequested 的值所做的改变。没有同步虚拟机可能会将:

while(!done)
{
    i++
}

优化为:

if(!done)
{
    while(true)
    {
        i++;
    }
}

虽然在我的机器上并没有出现和笔者机器上相同的现象,但是到网上去搜,听一些同学说出现了和笔者一致的现象。
我自己后来又到linux环境下实验,也仍然没有看到笔者的现象,暂且作罢,相信这是真的。

要修正这个问题,有两种方式:
方式一:同步访问stopRequested域

public class ThreadCommunication 
{
    private static boolean stopRequested = false;

    private static synchronized void requestStop()
    {
        stopRequested = true;
    }   
    private static synchronized boolean stopRequested()
    { 
        return stopRequested;
    }
    public static void main(String[] args) throws Exception
    {
        Thread backgroundThread = new Thread(new Runnable(){
            public void run()
            {
                int i=0;
                while(!stopRequested())
                {
                    i++;
                }
            }
        });

        backgroundThread.start();

        Thread.sleep(10);

        requestStop();  
    }

}

第二种方式:声明stopRequested 为 volatile

    private static volatile boolean stopRequested = false;

volatile修饰符不执行互斥访问,但它可以保证任何一个线程在读取该域的时候都将看到最近刚刚被写入的值

初学者浅谈“进程间通信的同步和互斥的比较简单的作用和用法”

第一次发blog,若有错误请谅解和指导,谢谢!!!! 好了,我们回归正题: 随着时代的发展,线程应运而生。这是为什么呢?这是因为我们要进一步减少CPU的空转时间,支持多处理器以及减少上下文切换的开销,...
  • hbz1993
  • hbz1993
  • 2014年11月26日 19:26
  • 751

进程间同步和互斥

概念: 两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥· 也就是说,一个进程正在访问临界资源,另一个要访问该资源的进程必须等...
  • lishuandao
  • lishuandao
  • 2016年03月20日 18:37
  • 850

利用信号量机制解决进程同步和互斥问题

利用信号量机制解决进程同步和互斥问题   在讨论如何用信号量机制解决这个问题之前,我们应该先了解进程同步和互斥间的一些概念。 首先是进程间的两种关系:同步和互斥。所谓同步就是把异步环境下的一组并...
  • sinat_14840443
  • sinat_14840443
  • 2014年10月27日 15:35
  • 1460

进程互斥与同步的区别

转载自: http://zhidao.baidu.com/question/414593560.html 相交进程之间的关系主要有两种,同步与互斥。所谓互斥,是指散布在不同进程之间的若...
  • guan_feng1988
  • guan_feng1988
  • 2013年06月03日 18:16
  • 2482

Python 线程同步与互斥

什么是并发?在操作系统中,指一个时间段内有几个程序都处于已启动到运行结束之间的状态,并且这几个程序都是在同一个处理机上运行的,但任一个时间点却只有一个程序在处理机上执行。 注意并发与并行并不是同一个...
  • SeeTheWorld518
  • SeeTheWorld518
  • 2015年11月04日 18:38
  • 2008

共享内存+互斥量实现linux进程间通信

一、共享内存简介     共享内存是进程间通信中高效方便的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针,两个进程可以对...
  • K346K346
  • K346K346
  • 2015年03月26日 17:14
  • 4242

进程间互斥与同步

进程间互斥与同步实验题目:进程间的互斥与同步 实验内容:编写算法,实现进程间对临界资源的互斥访问以及进程间的同步关系 实验要求: 1、要求进程互斥使用文本文件; 2、假定文本文件txt...
  • scylhy
  • scylhy
  • 2017年05月15日 22:18
  • 661

多线程同步与互斥(3)

在进行多线程编程时,难免还要碰到两个问题,那就线程间的互斥与同步: 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时...
  • Xp275500976
  • Xp275500976
  • 2012年02月02日 10:02
  • 16171

进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)

一、管道 在Linux 中,管道是一种使用非常频繁的通信机制。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现如下所述。 • 限制管道...
  • Simba888888
  • Simba888888
  • 2013年09月16日 19:43
  • 5545

多线程并发编程(四):多线程同步互斥Wait/Notify

前言 前面说了使用Synchronized来进行线程之间的同步,接下来说明wait/notify的使用。 首先wait/notify必须结合synchronized来使用,即在synch...
  • saytime
  • saytime
  • 2016年04月19日 17:16
  • 943
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:为了在线程间进行可靠的通信,也为了互斥访问,同步是必要的。
举报原因:
原因补充:

(最多只允许输入30个字)