精华内容
下载资源
问答
  • 同步和阻塞

    2019-03-29 14:10:20
    同步和异步针对应用程序来,关注的是程序中间的协作关系;阻塞与非阻塞更关注的是单个进程的执行状态。 同步:执行一个操作之后,等待结果,然后才继续执行后续的操作。 异步:执行一个操作后,可以去执行其他的...

    同步和异步针对应用程序来,关注的是程序中间的协作关系;阻塞与非阻塞更关注的是单个进程的执行状态。

    同步:执行一个操作之后,等待结果,然后才继续执行后续的操作。

    异步:执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作。

    阻塞:进程给CPU传达一个任务之后,一直等待CPU处理完成,然后才执行后面的操作。

    非阻塞:进程给CPU传达任我后,继续处理后续的操作,隔断时间再来询问之前的操作是否完成。这样的过程其实也叫轮询。

    阻塞、非阻塞、多路IO复用,都是同步IO,异步必定是非阻塞的,所以不存在异步阻塞和异步非阻塞的说法。真正的异步IO需要CPU的深度参与。换句话说,只有用户线程在操作IO的时候根本不去考虑IO的执行全部都交给CPU去完成,而自己只等待一个完成信号的时候,才是真正的异步IO。所以,拉一个子线程去轮询、去死循环,或者使用select、poll、epool,都不是异步。

    展开全文
  • <br />在http://hi.baidu.com/deep_pro/blog/item/cf964b0ade9f4d1594ca6b1b.html<br />  这些词之间的区别难倒了很多人,还有什么同步阻塞同步阻塞, 异步阻塞, 异步非阻塞,乱七八糟的。...

    http://hi.baidu.com/deep_pro/blog/item/cf964b0ade9f4d1594ca6b1b.html

     

    这些词之间的区别难倒了很多人,还有什么同步阻塞, 同步非阻塞, 异步阻塞, 异步非阻塞,乱七八糟的。
    很多文章也想讲明白这个问题。著名且引起热议的有

    http://www.ibm.com/developerworks/cn/linux/l-async/

    http://www.cppblog.com/converse/archive/2009/05/13/82879.html

    可是看了之后还是有点将信将疑,跑到图书馆翻了UNP 第一卷,不愧是圣经级别的著作,似有所悟。
    UNP所述:
    POSIX定义中,同步IO操作:IO操作将导致请求进程阻塞,直到IO操作完成。
    异步IO操作:IO操作不导致请求进程阻塞

    UNP中总结的IO模型有5种之多
    阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,前四种都属于同步IO。

    阻塞IO不必说了
    非阻塞IO ,IO请求时加上O_NONBLOCK一类的标志位,立刻返回,IO没有就绪会返回错误,需要请求进程主动轮询不断发IO请求直到返回正确
    IO复用同非阻塞IO本质一样,不过利用了新的select系统调用,由内核来负责本来是请求进程该做的轮询操作。看似比非阻塞IO还多了一个系统调用开销,不过因为可以支持多路IO,才算提高了效率
    信号驱动IO,调用sigaltion系统调用,当内核中IO数据就绪时以SIGIO信号通知请求进程,请求进程再把数据从内核读入到用户空间,这一步是阻塞的。
    异步IO,如定义所说,不会因为IO操作阻塞,IO操作全部完成才通知请求进程。

    这样以来,同步和阻塞,异步和非阻塞就不会被混淆了,它们不是同一个方面上的概念,不能比较区别

    同步和异步是只跟IO操作过程中进程的状态变化有关
    阻塞和非阻塞就是进程的两种状态。

     

    Unix下的五种I/O模型是:

    阻塞I/O

    非阻塞I/O

    I/O复用(select 和poll)

    信号驱动I/O

    异步I/O

    阻塞I/O模型图:

    非阻塞IO模型图解:

    IO复用模型图解:

    信号驱动IO图解:

    异步IO模型图解:

    同步IO引起进程阻塞,直至IO操作完成。

    异步IO不会引起进程阻塞。

    IO复用是先通过select调用阻塞。

    好了,上图已经解释的很清楚了,再来一张书中的综合图解:

    以上这些应该解释的足够清楚了吧 ~~~

    展开全文
  • java提供了同步机制来实现一个临界区,当一个线程想要访问一个临界区,它使用其中的一个同步机制来找出是否有任何其他线程执行临界 区。如果没有,这个线程就进入临界区。否则,这个线程通过同步机制暂停直到另一个...

    并发编程系列之基础篇(三)—线程的同步和阻塞

    前言

    大家好,牧码心今天给大家推荐一篇并发编程系列之基础篇(三)—线程的同步和阻塞的文章,希望对你有所帮助。具体内容如下:

    • 同步和阻塞概要
    • 为什么需要同步
    • 实现同步的方式

    同步和阻塞概要

    在并发编程中,我们常会碰到线程的同步,异步,阻塞和非阻塞等场景,其中同步和异步,是线程之间的方式,两个线程之间要么是同步的,要么是异步的;阻塞和非阻塞是线程内的状态,在某个时刻,线程要么处于阻塞,要么处于非阻塞。那它们分别是什么呢?

    • 同步:指线程在发起调用请求时,需要等待被调用者返回结果,才会进行后面的步骤。

    • 异步:指线程在发起调用请求时,调用者不需要等待被调用者返回调用,即可进行下一步操作,被调用者通常依靠事件、回调等机制来通知调用者结果。

    • 阻塞:指线程在发起调用请求时,在返回结果前,此线程会被挂起,处于等待状态;

    • 非阻塞:指线程在发起调用请求时不能立刻得到返回结果,此线程不会被被挂起,处于运行态;

    上述概念我们可以用一个例子说明:

    比如你打餐饮店客服电话需要订位。同步方式则是你需要一直等客服给你排好座位后,你才能挂断电话。其中过程是阻塞的。异步方式则是你可以提前挂断电话去做其他事,餐饮店客服以回电话或消息通知你订位的结果,其中过程是非阻塞。

    同时这几个概念又可以组合成以下4种方式:

    • 同步阻塞
    • 同步非阻塞
    • 异步阻塞
    • 异步非阻塞

    本文主要线介绍实现线程同步和实现同步的方式。对于线程阻塞,中断等分析详见后续系列文章。

    为什么需要线程同步

    当有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序执行结果异常。比如一个银行账户同时被两个线程操作,一个取100块,一个存钱100块。假设账户原本有0块,如果取钱线程和存钱线程同时发生,则会出现账户金额不准确的现象。而多线程同步就是要解决这个问题。

    • 示例演示
    public class Account {
    
        // 余额
        private double balance;
        // 存款
        public void addAmount(double amount,String threadName){
    
            balance+=amount;
            System.out.println(threadName+"-存款:"+amount);
        }
        // 取款
        public  void subAmount(double amount,String threadName){
            if(balance-amount<0){
                System.out.println("余额不足!");
                return;
            }
            balance-=amount;
            System.out.println(threadName+"-取款:"+amount);
        }
        // 查询余额
        public void queryAmount(String threadName){
            System.out.println(threadName+"-当前账户余额:"+balance);
        }
    
        public static void main(String[] args) {
            Account account=new Account();
            // 模拟存款
            Thread addThread=new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i=0;i<3;i++){
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        account.addAmount(200,Thread.currentThread().getName()+"-"+i);
                        account.queryAmount(Thread.currentThread().getName()+"-"+i);
                        System.out.println("\n");
                    }
                }
            });
            // 模拟取款
            Thread subThread=new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int j=0;j<3;j++){
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        account.subAmount(100,Thread.currentThread().getName()+"-"+j);
                        account.queryAmount(Thread.currentThread().getName()+"-"+j);
                        System.out.println("\n");
                    }
                }
            });
            addThread.start();
            subThread.start();
        }
    }
    
    • 运行结果
    余额不足!
    Thread-0-0-存款:200.0
    Thread-0-0-当前账户余额:200.0
    Thread-1-0-当前账户余额:200.0
    Thread-0-1-存款:200.0
    Thread-0-1-当前账户余额:400.0
    Thread-1-1-取款:100.0
    Thread-1-1-当前账户余额:300.0
    Thread-0-2-存款:200.0
    Thread-0-2-当前账户余额:500.
    Thread-1-2-取款:100.0
    Thread-1-2-当前账户余额:400.0
    

    从运行结果看,若未使用线程同步机制则运行结果会出现无序和不正确的情形。

    实现线程同步的方式

    在java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁是依赖于对象而存在。当我们调用某对象的synchronized方法时,就获取了该对象的同步锁。例如,synchronized(obj)就获取了“obj这个对象”的同步锁。
    不同线程对同步锁的访问是互斥的。也就是说,某时间点,对象的同步锁只能被一个线程获取到!通过同步锁,我们就能在多线程中,实现对“对象/方法”的互斥访问。 例如,现在有两个线程A和线程B,它们都会访问“对象obj的同步锁”。假设,在某一时刻,线程A获取到“obj的同步锁”并在执行一些操作;而此时,线程B也企图获取“obj的同步锁” —— 线程B会获取失败,它必须等待,直到线程A释放了“该对象的同步锁”之后线程B才能获取到“obj的同步锁”从而才可以运行。

    • synchronized方式
      使用synchronized可以修饰方法,代码块,以及静态资源等。此时线程访问synchronized修饰的资源,需要先获得同步锁,否则就处于阻塞状态。

      • 修饰方法:会锁住整个方法,需要访问改方法时,需要获得同步锁。
      • 修饰代码块:锁的粒度更细,并且充当锁的对象不一定是this,也可以是其它对象,使用起来更加灵活。
      • 修饰静态资源:若锁的对象是静态变量或静态资源,则会锁住整个类。

      注:同步是一种高开销的操作,因此应该尽量减少同步的内容。通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。

    • volatile (特殊域变量)方式
      volatile 修饰的成员变量在每次被线程访问时,都需要从共享内存中重读该成员变量的值。而且当成员变量发生变化时,线程将变化值回写到共享内存。如线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B。只在某些动作时才进行A和B的同步,因此存在A和B不一致的情况。volatile就是用来避免这种情况的。 volatile告诉jvm,它所修饰的变量不保留拷贝,直接访问主内存中的。

      volatile 变量具有 内存可见性特性,有序性,但是不具备原子特性,不能替代synchronized ,需要使用它用于线程安全,则需要满足:
      1.该变量没有包含在具有其他变量的不变式中;
      2.对变量的写操作是原子操作,如不适合自增的i++ 包含了读去,修改等操作;

    • 重入锁方式
      在jdk 5.0开始新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁, 它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。

    • ThreadLocal方式
      ThreadLocal 保证不同线程拥有不同实例,相同线程一定拥有相同的实例,即为每一个使用该变量的线程提供一个该变量值的副本,每一个线程都可以独立改变自己的副本,而不是与其它线程的副本冲突。ThreadLocal 是采用空间隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源,这样当然不需要多个线程进行同步了。

    • 原子类的方式
      需要使用线程同步的根本原因在于对普通变量的操作不是原子的。而原子操作就是指将读取变量值、修改变量值、保存变量值看成一个整体来操作,即-这几种行为要么同时完成,要么都不完成。如jdk的java.util.concurrent包中提供了创建了原子类型变量的工具类。如AtomicInteger/AtomicLong … 等

    展开全文
  • 同步和异步、阻塞和非阻塞 首先说明我对这些概念也不是很清楚,以下内容是我做的一些理事。 同步和异步、阻塞和非阻塞这是两组概念,说的是不同的事情,同步和阻塞没有必然的联系,异步和非阻塞也没有必然的...

    同步和异步、阻塞和非阻塞

    首先说明我对这些概念也不是很清楚,以下内容是我做的一些理事。

    同步和异步、阻塞和非阻塞这是两组概念,说的是不同的事情,同步和阻塞没有必然的联系,异步和非阻塞也没有必然的联系。同步和异步是只跟IO操作过程中进程的状态变化有关。阻塞和非阻塞就是进程的两种状态。比如你去银行,排除的话就是一种同步的方式,叫号的话就是异步的方式。排队必须自己看着什么时候轮到自己,而叫号则不必,轮到你的时候会触发一个事件,或者说你会收到一个信号,别人会叫你。不管是排除还是叫号,如果你在等待的过程中不能做其他事情,那就是阻塞模式,否则就是非阻塞模式。同步的时候可以有阻塞和非阻塞,异步的时候也可以有阻塞和非阻塞。

    阻塞 I/O

    Linux下的I/O操作默认是阻塞I/O,即open和socket创建的I/O都是阻塞I/O。当读写操作没有完成时,函数就不会返回,进程一直阻塞在那里。

    非阻塞I/O    

    非阻塞模式的使用并不普遍,因为非阻塞模式会浪费大量的CPU资源。

    网络编程时listen,recvfrom,connect都会引起阻塞。非阻塞IO通常应用于网络编程中,IO请求时加上O_NONBLOCK一类的标志位,函数立刻返回,IO没有就绪会返回错误,需要请求进程主动轮询不断发IO请求直到返回正确
    比如调用recvfrom时,如果系统还没有接收到网络数据,内核马上返回一个 EWOULDBLOCK的错误。

     当一个应用程序使用了非阻塞模式的套接字,它需要使用一个循环来不停地测试是否一个文件描述符有数据可读(称做 polling(轮询))。应用程序不停的 polling 内核来检查是否 I/O操作已经就绪。这将是一个极浪费 CPU资源的操作。这种模式使用中不是很普遍。

    I/O多路复用

    针对批量IP操作时,使用I/O多路复用,非常有好。

    在使用 I/O 多路技术的时候,我们调用 select()函数和 poll()函数或epoll函数(2.6内核开始支持),在调用它们的时候阻塞。
    当我们调用 select函数阻塞的时候,select 函数等待数据报套接字进入读就绪状态。当select函数返回的时候, 也就是套接字可以读取数据的时候。 这时候我们就可以调用 recvfrom函数来将数据拷贝到我们的程序缓冲区中。
    IO复用同非阻塞IO本质一样,不过利用了新的select系统调用,由内核来负责本来是请求进程该做的轮询操作。看似比非阻塞IO还多了一个系统调用开销,不过因为可以支持多路IO,才算提高了效率。多路复用的高级之处在于:它能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。

    异步I/O

          当我们运行在异步 I/O 模式下时,我们如果想进行 I/O 操作,只需要告诉内核我们要进行 I/O 操作,然后内核会马上返回。具体的 I/O 和数据的拷贝全部由内核来完成,我们的程序可以继续向下执行。当内核完成所有的 I/O 操作和数据拷贝后,内核将通知我们的程序
    展开全文
  • 同步阻塞同步阻塞,异步阻塞,异步非阻塞区别关系
  • NIO同步阻塞同步阻塞

    万次阅读 2019-02-27 15:09:26
    IO与NIO区别:其本质就是阻塞和非阻塞的区别。 阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,就会一直等待,直到传输完毕为止。 非阻塞概念:应用程序直接可以获取已经准备就绪好的数据,无需等待...
  • 同步异步和阻塞阻塞

    千次阅读 2016-07-21 15:40:02
    下面的内容不一定对,但是有利于理解同步异步和阻塞非阻塞。 同步异步和阻塞非阻塞是从不同层面定义的。...阻塞非阻塞指的是进程在等待I/O结果时的状态阻塞和非阻塞是进程在等待调用I/O结果(消息,返回值)时的状
  • 一个你烧开水的例子:1、你开始烧开水,你就站在那里不停地看着水开没开,直到水开了--同步阻塞;2、你开始烧开水,你不在那里干等着,而是去玩会手机,但是你每隔段时间会来看看水开没开,直到水开了--同步阻塞;...
  • 简单理解什么是同步阻塞/同步阻塞,异步阻塞/异步非阻塞 举个栗子 1、你在家做饭,用普通的汤锅,米放进去,就站在锅边,傻等饭熟。——这叫同步阻塞 是不是觉得浪费了大量的时间,于是你想提高时间的利用效率。 2...
  • NIO编程(同步阻塞同步阻塞详解)

    万次阅读 多人点赞 2018-02-22 15:56:50
    NIO同步阻塞同步阻塞 BIO与NIO IO为同步阻塞形式,NIO为同步阻塞形式,NIO并没有实现异步,在JDK1.7后升级NIO库包,支持异步非阻塞 同学模型NIO2.0(AIO) BIO(同步阻塞式IO) 同步阻塞式IO,服务器...
  • 同步是个过程,阻塞是线程的一种状态。多个线程操作共享变量时可能会出现竞争。这时需要同步来防止两个以上的线程...线程同步的时候,需要协调推进速度,互相等待互相唤醒会发生阻塞。 同样,阻塞也不一定同步。 ...
  • 网上闲逛技术贴,看见一个关于理解同步阻塞同步阻塞、异步阻塞、异步非阻塞比较风趣的故事,简单明了,很容易理解,因此记录一下,希望更多人能看见。 故事原文: 老张爱喝茶,废话不说,煮开水。出场人物:老张...
  • 异步or 同步 关注的是 发出调用后,当前这个调用是否直接返回,不管是否有返回结果<调用的结果> 阻塞还是非阻塞关注的是:程序等待调用的结果<返回值>的状态,在无法得到返回值的情况下,调用是否会阻塞...
  • 主要介绍了java 同步、异步、阻塞和非阻塞分析的相关资料,需要的朋友可以参考下
  • 同步阻塞:客户揣发送请求给服务揣,此时服务端处理任务时间很久,则客户端则被服务端堵塞了,所以客户端会一直等待服务端的响应,此时客户端不能做其他任何事,服务端也不接受其他客户揣的请求。这种通信机制比较...
  • 同步、异步、阻塞和非阻塞

    千次阅读 2014-12-08 20:18:50
    表面上看,同步和阻塞都是没干完,就等着干完;异步阻塞都是没干完,先干别的吧,好像很类似! 实际上,同步和异步是对调用方而言,比如说同步函数、异步函数,异步函数里有个参数是回调函数; 而阻塞、非阻塞...
  • 之前看到一个链接,是关于其中对于阻塞和非阻塞的区别的一个链接 ...其中讲解的很详细,基本上对什么是阻塞和什么是非阻塞的区别理解更深了一层。...同步和非同步是站在应用角度来看,而阻塞和非阻塞是站
  • 面试问我同步、异步、阻塞阻塞,答的并不是很好,回来后必然要出一篇博文加深印象了
  • 线程同步阻塞的关系?同步一定阻塞吗?阻塞一定同步吗? 同步是个过程,阻塞是线程的一种状态。...线程同步不一定发生阻塞,线程同步的时候,需要协调推进速度,互相等待互相唤醒会发生阻塞。 ...
  • 阻塞和非阻塞 阻塞调用是指调用结果返回之前,调用者会进入阻塞状态等待。只有在得到结果之后才会返回。 非阻塞调用是指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。   2.同步与异步 同步...
  • 同步堵塞

    2019-09-03 12:56:03
    同步阻塞 老王想了想,这种方法不够聪明。 2.老王还是用水壶煮水,不再傻傻的站在那里看水开,跑去寝室上网,但是还是会每隔一段时间过来看看水开了没有,水没有开就走人。-同步阻塞 老王想了想...
  • 同步是:每次自己主动的去问要结果 异步是:不用管,等好了会通知我的 集群:是不同的机器做相同的事 分布式是:每个模块都单独的独立处理,...同步阻塞的  普通水壶不在旁边看 ------&gt;同步阻塞的  ...
  • js异步和同步阻塞和非阻塞、进程和线程的总结 1.什么是单线程和多线程 在编程语言中,有的语言是多线程的,有的是单线程的,比如java就是多线程的,javascript是单线程的。 也就是说js就像一条流水线,只能在这...
  • 同步和异步】 同步和异步关注的是
  • 同步/异步 阻塞/非阻塞 的区别

    千次阅读 2017-02-21 17:38:03
    同步 异步 阻塞阻塞

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 420,061
精华内容 168,024
关键字:

同步和堵塞