这是why技术的第14篇原创文章 在实际开发过程中我踩到了mybatis的一个坑,我觉得值得记录、分享一下。 先说说这个坑是什么吧。...在org.apache.ibatis.logging.jdbc.BaseJdbcLogger的143行,debug方法中打印了日志,这行日志就是我的突破口。...是的,我无脑的使用了CV大法。导致我在欢声笑语中写出了bug。我orderStatus传入的类型是一个Byte,和""做判断有任何意义吗?...最后说几句 在解决这个问题之后,我还是在网上查了一圈,发现也有人遇到了这样的问题,但是我点开搜索出来的第一篇就是一个错误的描述,他说在mybatis中会把0当做null来处理?哥们你看源码了吗?...我之前在《面试了15位来自211/985院校的2020届研究生之后的思考》这篇文章中写到一段话,用在这里也很合适: ?
在实际开发过程中我踩到了mybatis的一个坑,我觉得值得记录、分享一下。 先说说这个坑是什么吧。如果你踩过这个坑,并且知道具体的原因,那这篇文章可以加深你的印象。...在org.apache.ibatis.logging.jdbc.BaseJdbcLogger的143行,debug方法中打印了日志,这行日志就是我的突破口。...是的,我无脑的使用了CV大法。导致我在欢声笑语中写出了bug。我orderStatus传入的类型是一个Byte,和""做判断有任何意义吗?...最后说一句 在解决这个问题之后,我还是在网上查了一圈,发现也有人遇到了这样的问题,但是我点开搜索出来的第一篇就是一个错误的描述,他说在mybatis中会把0当做null来处理?哥们你看源码了吗?...我之前在《面试了15位来自211/985院校的2020届研究生之后的思考》这篇文章中写到一段话,用在这里也很合适: ?
这里是《壹齐学多线程》系列的第 3 篇 生产者 - 消费者模型 Producer-consumer problem 是一个非常经典的多线程并发协作的模型,在分布式系统里非常常见。...问题背景 简单来说,这个模型是由两类线程构成: 生产者线程:“生产”产品,并把产品放到一个队列里; 消费者线程:“消费”产品。 队列:数据缓存区。 ?...在 Q2 里,其实只有一个线程,因为这里我们必须要加锁才能进行操作。 实现 这里我首先建了一个简单的 Product 类,用来表示生产和消费的产品,大家可以自行添加更多的 fields。...总结:在使用线程的等待通知机制时,一般都要在 while 循环中调用 wait() 方法。 消费者线程是完全对称的,我们来看代码。...小结 生产者 - 消费者问题是面试中经常会遇到的题目,本文首先讲了该模型的三大优点:解藕,异步,平衡速度差异,然后讲解了等待/通知的消息机制以及在该模型中的应用,最后进行了代码实现。
生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。...如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。将来如果消费者的代码发生变化,可能会影响到生产者。...生产者直接调用消费者的某个方法,还有另一个弊端。由于函数调用是同步的(或者叫阻塞的),在消费者的方法没有返回之前,生产者只好一直等在那边。万一消费者处理数据很慢,生产者就会白白糟蹋大好时光。...我比较喜欢的一点是:Celery支持使用任务队列的方式在分布的机器、进程、线程上执行任务调度。然后我接着去理解什么是任务队列。 任务队列 任务队列是一种在线程或机器间分发任务的机制。...因为涉及到消息中间件,所以我先去选择一个在我工作中要用到的消息中间件(在Celery帮助文档中称呼为中间人),为了更好的去理解文档中的例子,我安装了两个中间件,一个是RabbitMQ,一个
于是,一个进程中至少有一个执行的流程(主线程),也可以开启新的执行流程(线程)。 线程变成了最小的调度单位。...协程 这一天,旺财被一个叫做生产者和消费者的问题折腾地死去活来,两个线程,一个线程向队列中放数据,另外一个从队列中取数据,处理起两个线程的协作就显得很麻烦,不但需要加锁,还得做好线程的通知和等待。...正在感慨多线程编程之难的时候, 旺财震惊地发现,小强用了一个极为简单的办法把生产者,消费者问题给解决了。...“正是这样,” 小强得意地说:“我打算把类似生产者,消费者这样的代码称为‘协程’, 这个协程有个重要的特点,就是完全被我所调度和掌控, 不用操作系统介入。” “这个协程和线程似乎很像啊。...对了,也许你注意到了,我这两个协程是'合作式'的,它们两个同一时刻只能有一个在运行。 实际上,我在底层可以用一个线程去执行这两个协程。
壹 首先先来解释下,什么是「生产者消费者模型」:生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例...该问题描述了共享固定大小缓冲区的两个线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。...与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。...以上是wiki百科对于模型的解释,用我的话总结一下就是:一个愿打,一个愿挨。 ? 从上图中可以看到生产者和消费者之间用中间类似一个队列一样的东西串起来。...,我们就可以把仓库中的货物想像成是一个个的url,生产者产生url链接,消费者获取url连接并从中得到数据,在队列的帮助下可以使用多线程加快爬虫速度。
2、等待通知机制的实现: wait()方法: 方法wait()的作用是使当前执行代码的线程进行等待,wait()方法是Object类的方法,该方法用来将当前线程置入“预执行队列”中,并且在wait所在的代码行处停止执行...set的值是1575270909669_589770446724800 此实例生产者生产一个产品,消费者消费一个产品,在代码中就是对ValueObject中的value值进行操作 (2)多生产与多消费...; System.out.println("我想当threadTest对象执行完毕后在执行"); System.out.println("但是上面代码中的sleep()中的值应该写多少呢");...System.out.println("答案是:根据不能确定"); } } 运行结果: 我想当threadTest对象执行完毕后在执行 但是上面代码中的sleep()中的值应该写多少呢 答案是:...我想当threadTest对象执行完毕后我在执行,我做到了 方法join的作用是使所属的线程对象x正常执行run()方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后再继续执行线程z后面的代码
服务器中的后台线程检查并删除七天或更早的消息。只要消息在服务器上,消费者就可以访问消息。它可以多次读取消息,甚至可以按收到的相反顺序读取消息。...消费者代码与生产者代码非常相似。我们首先创建一个对象java.util.Properties,设置其特定于消费者的属性,然后使用它来创建一个新对象KafkaConsumer。...将清单2中的消费者代码分为两部分来确保Consumer在退出之前关闭对象。...我将依次描述每个类。首先,ConsumerThread是一个内部类,它将topic名称和组名称作为其参数。在该类的run()方法中,它创建一个具有适当属性的KafkaConsumer对象。...在Consumer类中,我们创建一个新对象,并在另一个ConsumerThread线程中启动它。在ConsumerThead开始一个无限循环,并保持轮询新消息的topic。
一般我们把消息的发送者称为生产者,消息的接收者称为消费者;注意定义中的那两个字“异步”,通常生产者的生产速度和消费者的消费速度是不相等的;如果两个程序始终保持同步沟通,那势必会有一方存在空等时间;如果两个程序一持续运行的话...,消费者的平均速度一定要大于生产者,不然队列囤积会越来越多;当然,如果消费者没有时效性需求的话,也可以把消息囤积在队列中,集中消费。...说到这里,我们再来谈谈队列的分类,一般我们根据生产者和消费者的不同,可以把队列分为三类: 第一类是在一个应用程序内部(进程之间或者线程之间),相信大家学多线程时都写过“生产者消费者”程序,生产者负责生产...consumer 1KW:1千万条消息 1K:每个消息1K 我先对ActiveMQ在单机多Producer、多consumer的情况下的测试,结果比我想象中的好,官方的给出的一个数据是1-2K的数据,每秒...结果和预想的一样,在单机模型下,两者差异不大;而官方给的数据说生产者能达到50MB/S,消费者能达到100MB/S,生产者符合官方数据,而消费者我始终没有压到那么高的速度。
生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。...产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。 单单抽象出生产者和消费者,还够不上是生产者消费者模式。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。...如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。将来如果消费者的代码发生变化,可能会影响到生产者。...生产者直接调用消费者的某个方法,还有另一个弊端。由于函数调用是同步的(或者叫阻塞的),在消费者的方法没有返回之前,生产者只好一直等在那边。万一消费者处理数据很慢,生产者就会白白糟蹋大好时光。...我比较喜欢的一点是:Celery支持使用任务队列的方式在分布的机器、进程、线程上执行任务调度。然后我接着去理解什么是任务队列。 任务队列 任务队列是一种在线程或机器间分发任务的机制。
线程 操作系统提供了线程来解决这些问题,在同一个进程地址空间内实现了多个逻辑控制流(即线程),它们可以像进程一样调度,具体实现上: 每个线程对应一个栈,因此一个使用多线程的进程中有多个栈,而不是一个 这些线程共享代码段...下面假设我们要实现一个类似phread的线程库,请注意以下的伪代码都是运行在用户态而非内核态的。...否则把mutex加入到一个由自旋锁保护的等待队列中,拥有锁的线程在释放锁后将等待队列中的线程唤醒。 关于futex的更多详情可以参考linux内核级同步机制--futex....条件变量:同步线程 问题描述 这里就是经典的生产者消费者问题,假设我们同时运行n个生产者消费者,它们把任务发布到队列中,以及m个消费者线程,从同一个队列中获取任务并执行。...我们怎么去协调生产者和消费者的行为,当队列为空时消费者等待;当队列满时生产者等待。我们需要一个什么样的消息机制?互斥锁很明显满足不了需求,代码中的互斥锁只是用来保护队列的。
对于在具有数十个或数百个用例的多租户设置中运行的系统尤其如此,其中针对每个用例的调优不仅不切实际而且不可能。因此,我几乎坚持使用服务器和客户端的默认设置。...例如,在新生产者中,我们使用“group commit”类似的机制来确保在另一个I/O正在进行中时发起的任何记录被组合在一起。...这种额外的延迟似乎会影响我们的吞吐量。由于服务器上的代码路径非常相似,我们可以通过调整批处理来更好地改善这种影响,并允许客户端缓冲更多未完成的请求。 但是,本着避免特殊情况调整的原则,我没有这么做。...本次测试实际上从日志初始位置开始,因此它在做真正的读I/O。但是在生产环境中,消费者几乎完全从OS页面缓存中读取,因为它正在读取刚刚由某个生产者产生的数据(这些数据仍然在缓存中)。...这三个消费者属于同一个消费者组中的成员,即它们消费同样的topic。 和我们预期一样,我们看到消费能力线性扩展,几乎就是单个消费者吞吐量的3倍,这一点都不令人惊讶。
在面试的过程中,面试官会根据你的回答来不断的深入问你,来考察你对知识理解的深度。...jdk1.7和jdk1.8中hashmap的一些变化,1.8版本的hashmap会涉及到红黑树。 多线程 如何实现线程安全的hashmap? synchronized和lock的区别?...怎么停止一个线程,Thread类中各个api的用法,常用的四种线程池有哪些? 生产者消费者有哪些实现方式。...使用wait和notify怎么实现,使用阻塞队列实现生产者消费者,使用lock和condition实现生产者消费者等。 wait和notify为什么必须要在synchronized中写呢,实现原理?...数据库 事务的隔离级别 事务的传播机制 自己在多线程这块有些欠缺,有些问题不太懂,然后答得也不太好,基本是没戏了。在面试完后,得知面试官比我大一届,同时也给我许多建议。
每次执行迭代器的next()方法并返回后,该方法的上下文环境即消失了,也就是所有在next()方法中定义的局部变量就无法被访问了。...相比多线程,协程的好处是它在一个线程内执行,避免线程之间切换带来的额外开销,而且多线程中使用共享资源,往往需要加锁,而协程不需要,因为代码的执行顺序是你完全可以预见的,不存在多个线程同时写某个共享变量而导致出错的情况...我们来使用协程写一个生产者消费者的例子: def consumer(): last = '' while True: receival = yield last if receival is not...消费者consumer()函数是一个生成器函数,每次执行到yield时即挂起,并返回上一次的结果给生产者。...生产者producer()接收到生成器的返回,并生成一个新的值,通过send()方法发送给消费者。至此,我们成功实现了一个(伪)并发。
Entry Set 中阻塞了所有试图获得当前对象锁而失败的线程,Wait Set 中阻塞了所有在获得锁运行期间由于缺失某些条件而交出 CPU 的线程集合。...一个典型的线程同步问题 下面我们写一个很有意思的代码,实现操作系统中的生产者消费者模型,借助我们的 wait 和 notify 方法。...,消费者类随机的从仓库中取一个产品。...刚开始可能是生产者生产一个产品,消费者消费一个产品,而一旦消费者线程执行的速度超过了生产者,必然会由于仓库容量为空而被阻塞。...---- 文章中的所有代码、图片、文件都云存储在我的 GitHub 上: (https://github.com/SingleYam/overview_java) 欢迎关注微信公众号:OneJavaCoder
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。...在学习一些设计模式的过程中,如果先找到这个模式的第三者,能帮助我们快速熟悉一个设计模式。 生产者消费者模式实战 我和同事一起利用业余时间开发的Yuna工具中使用了生产者和消费者模式。...在1.0版本中我并没有使用生产者消费模式,而是使用单线程来处理, 因为当时只需要处理我们一个部门的邮件,所以单线程明显够用,整个过程是串行执行的。...我们在一个长连接服务器中使用了这种模式,生产者1负责将所有客户端发送的消息存放在阻塞队列1里,消费者1从队列里读消息,然后通过消息ID进行 hash得到N个队列中的一个,然后根据编号将消息存放在到不同的队列里...读者可以在平时的工作中思考下哪些场景可以使用生产者消费者模式,我相信这种场景应该非常之多,特别是 需要处理任务时间比较长的场景,比如上传附件并处理,用户把文件上传到系统后,系统把文件丢到队列里,然后立刻返回告诉用户上传成功
支持阻塞的插入方法:意思是当队列满时,队列会阻塞插入的元素,直到队列不满 支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空 阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素的线程...,如果队列为空则阻塞等待 返回头结点,从队列中移除头节点,队列中没元素会一直阻塞等待,指定时间已经过去还没能拿到头节点,则返回null 检查方法 不可用 不可用 例子 举一个多生产者,多消费者的例子,...notifyAll()[通知所有阻塞的线程]方法,而不是notify()[通知一个阻塞的线程]方法,因为有可能出现“生产者”唤醒“生产者”,消费者“唤醒”消费者的情况,因此有可能造成死锁,这里以1个消费者...生产者0 生产 生产者0 生产 生产者0 生产 消费者1 消费 消费者1 消费 消费者1 消费 生产者1 生产 把这个实例用阻塞队列来改写,先自己写一个阻塞队列,实现BlockingQueue接口,这里只展示了一部分重写的方法...最后说一下LZ的理解,个人感觉用ArrayBlockingQueue实现生产者和消费者,比我上面用synchronized的方式应该快很多,毕竟ArrayBlockingQueue只会是生成者通知消费者
以多线程编程中的经典案例生产者和消费者模型为例,我们先来演示一下线程“假死”的问题。...1.1 正常版本 在演示线程“假死”的问题之前,我们先使用 wait 和 notify 来实现一个简单的生产者和消费者模型,为了让代码更直观,我这里写一个超级简单的实现版本。...1.2 线程“假死”版本 当只有一个生产者和一个消费者时,wait 和 notify 方法不会有任何问题,然而将生产者增加到两个时就会出现线程“假死”的问题了,程序的实现代码如下: public class...切记 Lock 的 lock.lock() 方法不能放入 try 代码中,如果 lock 方法在 try 代码块之内,可能由于其它方法抛出异常,导致在 finally 代码块中, unlock 对未加锁的对象解锁...通过以上结果可以看出:当我们调用 notifyAll 时确实不会造成线程“假死”了,但会造成所有的生产者都被唤醒了,但因为待执行的任务只有一个,因此被唤醒的所有生产者中,只有一个会执行正确的工作,而另一个则是啥也不干
以多线程编程中的经典案例生产者和消费者模型为例,我们先来演示一下线程“假死”的问题。...1.1 正常版本 在演示线程“假死”的问题之前,我们先使用 wait 和 notify 来实现一个简单的生产者和消费者模型,为了让代码更直观,我这里写一个超级简单的实现版本。...1.2 线程“假死”版本 当只有一个生产者和一个消费者时,wait 和 notify 方法不会有任何问题,然而将生产者增加到两个时就会出现线程“假死”的问题了,程序的实现代码如下: public class...切记 Lock 的 lock.lock() 方法不能放入 try 代码中,如果 lock 方法在 try 代码块之内,可能由于其它方法抛出异常,导致在 finally 代码块中, unlock 对未加锁的对象解锁...,但因为待执行的任务只有一个,因此被唤醒的所有生产者中,只有一个会执行正确的工作,而另一个则是啥也不干,然后又进入等待状态,这就行为对于整个程序来说,无疑是多此一举,只会增加线程调度的开销,从而导致整个程序的性能下降
领取专属 10元无门槛券
手把手带您无忧上云