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

原创 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修饰符不执行互斥访问,但它可以保证任何一个线程在读取该域的时候都将看到最近刚刚被写入的值

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

多线程——线程间的同步通信

1、概要 线程间的相互作用:线程之间需要一些协调通信,来共同完成一件任务。 线程间的协调通信主要通过wait方法和notify方法来完成。 因为wait和notify方法定义在...

Linux进程间通信与线程间同步详解(全面详细)

引用:http://community.csdn.net/Expert/TopicView3.asp?id=4374496 linux下进程间通信的几种主要手段简介:    1. 管道(Pip...

黑马程序员—多线程线程间的通信与同步新特性

一、线程间通信。 等待/唤醒机制:也就是常见的生产者消费者问题。 1.当多个生产者消费者出现时,需要让获取执行权的线程判断标记。 通过while完成。 2.需要将对方的线程唤醒。仅仅用notif...

线程间的通信与同步

线程间的通信与同步

java多线程之线程间同步通信

public class ConditionCommunication { /** * @param args */ public static void main(String[] a...

线程间同步.zip

  • 2016-03-04 16:43
  • 438KB
  • 下载

线程间的通信、同步方式与进程间通信方式

1、线程间的通信方式 使用全局变量主要由于多个线程可能更改全局变量,因此全局变量最好声明为violate 使用消息实现通信在Windows程序设计中,每一个线程都可以拥有自己的消息队列(UI线程默认自...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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