`
longgangbai
  • 浏览: 7325515 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java中 对共享可变数据的同步访问

阅读更多

 对共享可变数据的同步访问
        synchronized  关键字可以保证在同一个实践,只有一个线程在执行一条语句,
  或者一段代码块。不同概念不仅包括互斥,而且包括一个对象被一个线程修改的时候,
  可以阻止另一个线程观察到内部不一致的状态。
 
       当对象被创建的时候处于一直的状态,当有方法访问他的时候他就被锁定了,这些方法
  观察到对象的状态,并且可能会引起一个状态转变即把对象从一种一致的状态转化到另
  一种一致的状态。
 
        正确地使用同步可以保证其他任何方法都不会看到对象处于不一致的状态中。
 
 
 
 
 
 为了在线程之间可靠的通讯,以及为了互斥访问,同步是必须的(java内存模型的结构)。
 
 如果对一个共享变量的访问不能同步的话,其结果将是非常可怕的,即使这个变量是原子可读写的。
 
 
 下面实例,因为没有同步,读和写是相互独立的操作,按顺序执行,因此多个并发的线程可能看到nextSerialNumber域中的同样的值,因为返回相同的序列号如果没有同步机制的情况下,一个线程可能根本看不到其他下线程所做的更改。这个内存模型所导致的结果。

修改前:

 

class GenerateSerialNumber {

private static int nextSerialNumber=0;

public static int generateSerialNumber()

{

 return nextSerialNumber++;

}

}


 

 

 

 

修改后:

 

class GenerateSerialNumberExt {

 private static int nextSerialNumber=0;

 public synchronized static int generateSerialNumber(){

return nextSerialNumber++;

 }

}


 

 

 

 

 

     下面介绍一种常见的线程同步问题,因为他们本质的是不安全的。
 他们会导致对象被破坏。为了终止一个线程,常见的做法,只要让线程
 轮询某一个域,该域的值如果发生变化,就表明此线程应该终止自己,通常
 这个域是一个boolean,或者一个对象的引用。因为读或者写这样 的域是
 原子操作,所以有些程序员在访问该域的适合就不再使用同步。
 

 

修改前:

class StoppableThread extends Thread {

 private boolean stopRequested=false;

 @Override public void run(){

boolean done=false;

while(!stopRequested && !done){ }

 }

public void requestStop(){

stopRequested=true;

 }

public boolean stopRequest(){

 return stopRequested;

}

}

 


 

 

 

 


  原因如下:
        由于缺少同步,所以并不能保证这个可终止的线程将会”看到“其他线程对
 stopRequested的值所做的更改,其结果是requestStop()方法有可能完全无效。
 除非你是在一台多处理器的及其上运行。否则你在实践中不可能观察到这样的错误行为。
 但是这是没有保证的。修改这个问题最直接的办法是,对stopRequested的域的所有访问
 都添加同步的特性。

 

修改方案一:

 

 

 

class StoppableThreadExt extends Thread {

private volatile boolean stopRequested=false;

@Override public void run(){

 boolean done=false;

while(!stopRequested && !done){

 

 } }

public void requestStop(){

 stopRequested=true;

}

public boolean stopRequest(){

return stopRequested;

}

}

 


 

 


 

 

 

 

     注意:这里每一个被同步的方法中的动作都是源自的,使用同步的
  唯一目的是为了通信。而不是互斥访问。修正之后的代码可以正常
  工作,while循环的每次迭代中同步开销并不显著,有一个正确的方法
  其代码并不冗长,性能也是比较好的,如果stopRequested被声明为
  volatile的话,则同步可以被忽略,volatile 修饰符可以保证任何一个线程
  在读取一个域的适合将会看到最近刚刚被写入的值

 

 

修改方案二:

class StoppableThreadExtion extends Thread {

private boolean stopRequested=false;

@Override

public void run(){

boolean done=false; while(!stopRequested && !done){

 } }

public synchronized void requestStop(){

stopRequested=true; }

public synchronized boolean stopRequest(){

return stopRequested;

}

}

 


 

 

 

 

 

分享到:
评论

相关推荐

    java 线程同步 信号量控制同步

    无论是否执行同一份代码,只要这些线程的代码访问同一份可变的共享资源,这些线程之间就需要同步。 线程同步机制可以通过使用锁来实现。锁可以是对象锁、类锁或同步锁。锁的作用是防止多个线程同时访问同一个共享...

    深入同步访问共享的可变数据分析

    本篇文章是对同步访问共享的可变数据进行了详细的分析介绍,需要的朋友参考下

    JAVA实现局域网桌面共享

    综上所述,JAVA实现局域网桌面共享涉及到网络编程、多线程、图像处理、数据传输协议等多个领域,而项目中提及的线程优化问题需要进一步关注和改进。通过不断优化和调试,这个应用可以变得更加健壮和高效。

    java线程同步详解

    3. **只有共享变量(可变状态)才需要同步,常量或不可变对象可以并发访问。** 4. **同步可以应用于方法或代码块,根据需求选择合适的同步策略。** 5. **Java提供了`synchronized`关键字以及更高级的并发工具来实现...

    java多线程同步分析

    Java多线程同步是编程中一个重要的概念,特别是在并发编程中,它用于管理多个线程对共享资源的访问,防止数据的不一致性。线程同步是解决多线程并发问题的关键,确保线程按照一定的顺序执行,避免竞态条件。 线程在...

    Java共享内存并行编程

    ### Java共享内存并行编程 #### 1. 引言 随着计算机技术的发展,特别是多核处理器的普及,高效利用多核架构成为提高程序性能的关键因素之一。Java作为一种跨平台的语言,不仅在Web开发、企业级应用等领域有着广泛...

    JAVA实现Modbus RTU或Modbus TCPIP数据采集.rar

    5.将复合操作放在一个原子操作中执行,或用相同的锁来保护每个共享的和可变的变量。 6.增加同步必然会导致代码的复杂性,为性能牺牲代码简单性时不要太盲目,因为越复杂的代码,其不安全性越大。

    Java中的线程安全与线程同步.doc

    在实际编程中,除了使用这些同步机制外,我们还可以通过设计无状态对象、不可变对象以及使用线程局部变量(ThreadLocal)等方式来减少线程安全问题的发生。同时,避免使用静态变量存储线程相关的状态,尽量减少共享...

    多数据源数据同步,数据接口

    在IT行业中,多数据源数据同步和数据接口是企业级应用开发中不可或缺的部分,尤其是在大数据时代,数据的整合、共享和实时更新变得至关重要。这里我们将深入探讨如何在Java Spring Boot框架下实现这些功能。 首先,...

    Java文件同步程序

    在给出的压缩包"bin"中,通常包含的是编译后的可执行文件或类库,用户可以直接运行或导入到Java项目中使用。为了自定义和扩展这个文件同步程序,用户可能需要查看源代码,了解其内部工作原理,并根据实际需求进行...

    java多线程_java多线程下变量共享_

    - 尽量减少共享状态,如果必须共享,使用不可变对象。 - 使用最小粒度的锁,避免锁的粒度过大导致的阻塞。 - 避免死锁,确保线程间的资源获取顺序不会形成环路。 - 使用`ThreadLocal`存储线程私有数据,避免全局变量...

    Java中的String为什么是不可变的?-String源

    在实际开发中,如果确实需要对字符串进行修改,Java提供了StringBuilder和StringBuffer类,它们是可变的,允许动态构建字符串。但是需要注意,这两个类在多线程环境下的使用需要考虑同步问题,以防止数据竞争。 总...

    java中的同步和异步的异同.docx

    - **多线程中对共享、可变的数据进行同步**:只有当数据是共享的,并且是可变的时候,才需要考虑同步问题。对于函数中的局部变量以及不可变数据,无需进行同步处理。 - **单个线程中的synchronized**:虽然可以在...

    Java同步与异步[定义].pdf

    同步是指使用锁机制来保护共享资源的访问,以确保数据的一致性和可见性。 3.什么叫原子的? 原子操作是指不会被打断地操作,能够保证数据的一致性。Java 中,32 位或者更少位数的赋值是原子的。 4.什么叫异步? ...

    读书笔记-Java并发编程实战-基础篇

    在Java并发编程中,数据的封装与访问控制、线程安全性的考量、同步机制的使用是重要的基础概念和技巧。以下是从给出的文件内容中提取出的详细知识点: 1. 数据封装与访问控制:确保内部私有数据不被轻易访问,并且...

    Java线程间同步互斥

    生产者和消费者共享一个数据,当数据为0 时,消费者不可访问,生产者可访问数据,每次访问数据加1;当数据到达100 时,生产者唤醒消费者,同时自身不可访问数据,消费者可访问数据,每次访问数据减1,直到数据为0,...

    java经典面试试题(从数据结构到设计模式)

    - `final`:声明常量或不可变对象。 - `float`:单精度浮点型数据类型。 - `for`:循环控制结构。 - `goto`:保留关键字,目前未使用。 - `if`:条件判断语句。 - `implements`:实现接口的关键字。 - `import`:...

    java同步和内存模型

    然而,在多线程环境下,尤其是随着现代多核处理器的普及,线程之间的交互变得复杂起来,这就需要一种机制来确保数据的一致性和线程的安全访问。 #### 二、Java中的同步概念 ##### 1. 原子性 原子性是指一个操作...

    java多线程设计

    本知识点将深入探讨Java多线程设计以及如何利用“不可变对象”(immutable objects)来避免多线程环境中的非安全问题。 一、Java多线程基础 1. 线程的创建:Java提供了两种创建线程的方式——继承Thread类和实现...

Global site tag (gtag.js) - Google Analytics