`

线程同步与异步

 
阅读更多

 

Java中的线程同步与异步如何理解?

 

同步和异步最大的区别就在于。一个需要等待,一个不需要等待。
比如广播,就是一个异步例子。发起者不关心接收者的状态。不需要等待接收者的返回信息
电话,就是一个同步例子。发起者需要等待接收者,接通电话后,通信才开始。需要等待接收者的返回信息

多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线

程的处理的数据,而B线程又修改了A线程处理的数理。显然这是由于全局资源造成的,有时为了解

决此问题,优先考虑使用局部变量,退而求其次使用同步代码块,出于这样的安全考虑就必须牺牲

系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制

 

同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求

不到,怎么办,A线程只能等待下去

异步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程

仍然请求的到,A线程无需等待

 

显然,同步最最安全,最保险的。而异步不安全,容易导致死锁,这样一个线程死掉就会导致整个

进程崩溃,但没有同步机制的存在,性能会有所提升

 

java中实现多线程

1)继承Thread,重写里面的run方法

2)实现runnable接口

 

举个例子:普通B/S模式(同步)AJAX技术(异步)

同步:提交请求->等待服务器处理->处理完返回这个期间客户端浏览器不能干任何事

异步:请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

可见,彼“同步”非此“同步”——我们说的java中的那个共享数据同步(synchronized)

一个同步的对象是指行为(动作),一个是同步的对象是指物质(共享数据)。

 

4、 Java同步机制有4种实现方式:(部分引用网上资源)

① ThreadLocal ② synchronized( ) ③ wait() 与 notify() ④ volatile

目的:都是为了解决多线程中的对同一变量的访问冲突

ThreadLocal
ThreadLocal 保证不同线程拥有不同实例,相同线程一定拥有相同的实例,即为每一个使用该

变量的线程提供一个该变量值的副本,每一个线程都可以独立改变自己的副本,而不是与其它线程

的副本冲突。

优势:提供了线程安全的共享对象

与其它同步机制的区别:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之

间进行通信;而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源

,这样当然不需要多个线程进行同步了。

 

 为了说明多线程访问对于类变量和ThreadLocal变量的影响,QuerySvc中分别设置了类变量sql和ThreadLocal变量,使用时先创建 QuerySvc的一个实例对象,然后产生多个线程,分别设置不同的sql实例对象,然后再调用execute方法,读取sql的值,看是否是set方法中写入的值。这种场景类似web应用中多个请求线程携带不同查询条件对一个servlet实例的访问,然后servlet调用业务对象,并传入不同查询条件,最后要保证每个请求得到的结果是对应的查询条件的结果。 在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻只有一个线程对共享变量进行操作。但在有些情况下,synchronized不能保证多线程对共享变量的正确读写。例如类有一个类变量,该类变量会被多个类方法读写,当多线程操作该类的实例对象时,如果线程对类变量有读取、写入操作就会发生类变量读写错误,即便是在类方法前加上synchronized也无效,因为同一个线程在两次调用方法之间时锁是被释放的,这时其它线程可以访问对象的类方法,读取或修改类变量。这种情况下可以将类变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立拷贝,不会出现一个线程读取变量时而被另一个线程修改的现象。  下面举例说明: 

public class QuerySvc {  

private String sql;  

private static ThreadLocal sqlHolder = new ThreadLocal();  

public QuerySvc() {  }  public void execute() { 

 System.out.println("Thread " + Thread.currentThread().getId() +" Sql is " + sql); 

 System.out.println("Thread " + Thread.currentThread().getId() +" Thread Local variable Sql is " + sqlHolder.get());  }  

 

public String getSql() {  

return sql;  }  

public void setSql(String sql) { 

  this.sql = sql;  sqlHolder.set(sql);  }

  } 

  

使用QuerySvc的工作线程如下:

public class Work extends Thread {  
private QuerySvc querySvc;  
private String sql;  
public Work(QuerySvc querySvc,String sql) {  
this.querySvc = querySvc;  this.sql = sql;  }  
public void run() {  querySvc.setSql(sql);  querySvc.execute();  }  } 
 运行线程代码如下: 
 QuerySvc qs = new QuerySvc();  
for (int k=0; k<10; k++)  
String sql = "Select * from table where id =" + k; 
 new Work(qs,sql).start();

  }

 


 原子操作及线程同步

为了提高性能,在读或写原子数据的时候,应该避免使用同步,这个是非常危险而且错误的,原因参见线程同步的第二条

 原子操作

atomic原子操作是CPU执行指令的最小单元,是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,在执行完毕之前不会被任何其它任务或事件中断。能够在单条指令中完成的操作都可以认为是" 原子操作",因为中断只能发生于指令之间。通常所说的原子操作包括对非longdouble型的primitive进行赋值,以及返回这两者之外的primitive。如果你在longdouble前面加了volatile,那么它就肯定是原子操作了。

 

线程同步

synchronized作用:

1. 互斥:保证一个线程里所看到的都是同一状态,不会出现一个线程执行过程中,共享数据被其他线程修改,引起状态转变,导致一个线程前后看到的东西处于不一致的状况。

2. 同步:保证在一个线程里所做的修改能够被其他线程所看到,避免由于JVM做如下代码优化,所导致多线程不能同步的问题。

    while(!done)

        i++;

JVM优化代码后转换成

    if(!done)

        while(true)

            i++;

    这样的话在另外一个线程修改了done可能会导致while循环永远不会退出,如果使用了synchronized,则不会做此优化,避免了此类问题的发生。

 

总结:当多个线程共享可变数据的时候,每个读或者写数据的线程都必须执行同步。如果只是为了同步(通信),而不是互斥访问,可以用volatile修饰变量,而不用synchronized方法,它可以保证在一个线程中读取的数据都是最新修改的,这样做可以提高性能,因为系统做同步的开销很大。

分享到:
评论

相关推荐

    c#线程同步与异步编程

    在C#编程中,线程同步与异步是并发编程中的关键概念,它们涉及到如何有效地管理多线程环境中的资源和执行顺序。本教程将深入探讨这两个概念,以帮助初学者更好地理解和应用。 同步编程是程序执行的一种方式,其中...

    线程同步与异步套接字编程

    在计算机编程领域,尤其是网络编程中,线程同步与异步套接字编程是至关重要的概念,它们直接影响到程序的性能、稳定性和可扩展性。本文将深入探讨这两个主题,并结合实际应用进行详细阐述。 首先,我们需要理解线程...

    vc++ 线程同步与异步套接字编程实例

    vc++ 线程同步与异步套接字编程实例,Windows套接字在两种模式下执行I/O操作,阻塞和非阻塞。在阻塞模式下,在I/O操作完成前,执行操作的Winsock函数会一直等待下去,不会立即返回程序(将控制权交还给程序)。而在非...

    C#多线程同步与异步的实现

    根据给定的文章信息,本文将深入探讨C#在.NET平台上进行多线程程序设计的方法,特别是多线程同步与异步的实现。 ### C#多线程同步与异步的实现 #### 一、多线程概念 多线程是现代操作系统支持的一种并发处理方式...

    Lesson16线程同步与异步套接字编程

    线程同步与异步套接字编程 线程同步与异步套接字编程

    C#多线程同步与异步的实现[归纳].pdf

    C#多线程同步与异步的实现[归纳].pdf

    C#多线程同步与异步的实现.pdf

    C#多线程同步与异步的实现.pdf

    C++的线程同步与异步套接字编程源码.zip

    在C++编程中,线程同步和异步套接字编程是两个重要的概念,尤其是在开发高性能、多用户并发的网络应用程序时。线程同步确保了数据的一致性和完整性,而异步套接字则提供了非阻塞的网络通信方式,提高了程序的执行...

    进程线程通信,线程同步,异步,进程通信经典进程间通信.7z

    在计算机科学中,进程线程通信、线程同步与异步以及进程间的通信是操作系统核心概念,对于理解和优化多任务并行处理至关重要。这些概念在软件开发,尤其是并发编程领域中占据着举足轻重的地位。 首先,让我们来探讨...

    visual c++ MFC之Lesson16线程同步与异步套接字编程

    在Visual C++ MFC编程中, Lesson16主要讲解了线程同步和异步套接字编程的关键概念和技术。线程同步是多线程编程中一个重要的方面,它确保了在共享资源时避免数据冲突和死锁。异步套接字编程则是Windows环境下网络...

    C# 多线程同步、异步_AutoResetEvent用法

    ### 二、线程同步与异步 **线程同步** 是指多个线程之间的协调,确保它们按照一定的顺序或规则执行。这有助于避免数据竞争和资源冲突,确保数据一致性。而**线程异步** 则允许线程并行执行,提高程序的并发性能,但...

    并发、多线程、同步异步概念.docx

    ### 并发、多线程、同步异步概念解析 #### 一、并发与多线程 **并发**(Concurrency)是指多个任务看起来同时进行的一种现象。在计算机领域,特别是操作系统层面,它指的是一个时间段内有多个程序或任务都在运行...

    vc 多线程实例同步,异步

    本实例主要探讨如何在VC++中创建多线程,尤其是工作者线程(Worker Threads)和用户界面(UI)线程,以及如何进行线程同步和异步操作。 首先,我们要理解线程的基本概念。线程是操作系统分配CPU时间的基本单元,一...

    线程同步与异步套接字VC++编程实例

    在计算机编程领域,尤其是涉及到多线程和网络通信时,线程同步与异步套接字的概念至关重要。本文将深入探讨这两个主题,并结合VC++编程环境进行实例解析。 线程同步是多线程编程中的一个关键概念,它主要用于管理...

    VC++ 线程同步与异步套接字编程实例

    结合上述技术,`VC++线程同步与异步套接字编程实例源码`可能包含以下部分: - 多线程处理网络连接请求,每个请求在一个单独的线程中处理,以防止阻塞主线程。 - 使用线程同步机制(如临界区或互斥量)保护共享资源...

    Java同步与异步[文].pdf

    Java同步与异步编程是多线程编程的核心内容,在Java中,线程同步与异步处理是保证程序正确执行的关键技术。本文将详细介绍Java中的线程同步机制、线程安全的实现以及异步执行的相关知识点。 首先,了解Java中的线程...

    spring线程池(同步、异步).docx

    2. `SyncTaskExecutor`:这是一个同步执行器,任务在同一线程中执行,不涉及多线程,适合用于同步调用,而非异步执行。 3. `ThreadPoolTaskExecutor`:这是Spring最常用的线程池实现,它包装了`java.util.concurrent...

    C++ 线程(串行 并行 同步 异步)详解

    C++ 线程(串行 并行 同步 异步)详解 C++ 线程是指在程序中可以同时执行多个任务的技术,通过线程可以提高程序的执行效率和响应速度。在 C++ 中,线程可以分为串行线程和并行线程两种。 串行线程(Serial Thread...

    C# 同步与异步读写

    在编程领域,尤其是在高性能和高并发的场景下,理解和掌握同步与异步读写是非常关键的。C#作为微软开发的面向对象的编程语言,提供了丰富的API和特性来支持这两种操作模式。本篇文章将深入探讨C#中的同步与异步读写...

    delphiXE多线程同步对象及异步执行.zip

    Delphi提供了各种同步对象,如TCriticalSection、TSemaphore、TMutex等,来实现线程同步。例如,TCriticalSection用于在多线程中保护临界区,确保同一时间只有一个线程能进入该区域。使用TryEnterCriticalSection和...

Global site tag (gtag.js) - Google Analytics