synchronized

Java编程的逻辑 (67) - 线程的基本协作机制 (上)

╄→尐↘猪︶ㄣ 提交于 2019-12-22 03:37:02
​ 本系列文章经补充和完善,已修订整理成书《Java编程的逻辑》,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接 : http://item.jd.com/12299018.html 上节 介绍了多线程之间竞争访问同一个资源的问题及解决方案synchronized,我们提到,多线程之间除了竞争,还经常需要相互协作,本节就来介绍Java中多线程协作的基本机制wait/notify。 都有哪些场景需要协作?wait/notify是什么?如何使用?实现原理是什么?协作的核心是什么?如何实现各种典型的协作场景?由于内容较多,我们分为上下两节来介绍。 我们先来看看都有哪些协作的场景。 协作的场景 多线程之间需要协作的场景有很多,比如说: 生产者/消费者协作模式:这是一种常见的协作模式,生产者线程和消费者线程通过共享队列进行协作,生产者将数据或任务放到队列上,而消费者从队列上取数据或任务,如果队列长度有限,在队列满的时候,生产者需要等待,而在队列为空的时候,消费者需要等待。 同时开始:类似运动员比赛,在听到比赛开始枪响后同时开始,在一些程序,尤其是模拟仿真程序中,要求多个线程能同时开始。 等待结束:主从协作模式也是一种常见的协作模式,主线程将任务分解为若干个子任务,为每个子任务创建一个线程

线程间协作:wait、notify、notifyAll

安稳与你 提交于 2019-12-22 03:36:34
转载: http://blog.csdn.net/ns_code/article/details/17225469 在 Java 中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信。在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调用notify()方法或notifyAll()方法),在线程中调用notify()方法或notifyAll()方法,将通知其他线程从wait()方法处返回。 Object是所有类的超类,它有5个方法组成了等待/通知机制的核心:notify()、notifyAll()、wait()、wait(long)和wait(long,int)。在Java中,所有的类都从Object继承而来,因此,所有的类都拥有这些共有方法可供使用。而且,由于他们都被声明为final,因此在子类中不能覆写任何一个方法。 这里详细说明一下各个方法在使用中需要注意的几点: 1、wait() public final void wait() throws InterruptedException,IllegalMonitorStateException 该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止。在调用wait()之前,线程必须要获得该对象的对象级别锁

Java多线程协作(wait、notify、 notifyAll)

狂风中的少年 提交于 2019-12-22 03:35:53
http://sunjun041640.blog.163.com/blog/static/25626832201041411210560/ Java监视器支持两种线程:互斥和 协作。 前面我们介绍了采用对象锁和重入锁来实现的互斥。这一篇中,我们来看一看线程的协作。 举个例子:有一家汉堡店举办吃汉堡比赛,决赛时有3个顾客来吃,3个厨师来做,一个服务员负责协调汉堡的数量。为了避免浪费,制作好的汉堡被放进一 个能装有10个汉堡的长条状容器中,按照先进先出的原则取汉堡。如果容器被装满,则厨师停止做汉堡,如果顾客发现容器内的汉堡吃完了,就可以拍响容器上的 闹铃,提醒厨师再做几个汉堡出来。此时服务员过来安抚顾客,让他等待。而一旦厨师的汉堡做出来,就会让服务员通知顾客,汉堡做好了,让顾客继续过来取汉 堡。 这里,顾客其实就是我们所说的消费者,而厨师就是生产者。容器是决定厨师行为的监视器,而服务员则负责监视顾客的行为。 在JVM中,此种监视器被称为等待并唤醒监视器。 在这种监视器中,一个已经持有该监视器的线程,可以通过调用监视对象的wait方法,暂停自身的执行,并释放监视器,自己进入一个等待区,直到监 视器内的其他线程调用了监视对象的notify方法。 当一个线程调用唤醒命令以后,它会持续持有监视器,直到它主动释放监视器。而这之后,等待线程会苏醒,其中的一个会重新获得监视器,判断条件状态,以便决

线程间协作:wait、notify、notifyAll

杀马特。学长 韩版系。学妹 提交于 2019-12-22 03:35:03
线程间协作:wait、notify、notifyAll 在 Java 中,可以通过配合调用 Object 对象的 wait() 方法和 notify()方法或 notifyAll() 方法来实现线程间的通信。在线程中调用 wait() 方法,将阻塞等待其他线程的通知(其他线程调用 notify() 方法或 notifyAll() 方法),在线程中调用 notify() 方法或 notifyAll() 方法,将通知其他线程从 wait() 方法处返回。 Object 是所有类的超类,它有 5 个方法组成了等待/通知机制的核心:notify()、notifyAll()、wait()、wait(long)和 wait(long,int)。在 Java 中,所有的类都从 Object 继承而来,因此,所有的类都拥有这些共有方法可供使用。而且,由于他们都被声明为 final,因此在子类中不能覆写任何一个方法。 这里详细说明一下各个方法在使用中需要注意的几点。 wait() public final void wait() throws InterruptedException,IllegalMonitorStateException 该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止。在调用 wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用 wait

java 线程(三) wait和notify方法

﹥>﹥吖頭↗ 提交于 2019-12-22 03:34:37
1.wait和notify相关概念: wait和notify方法是Java同步机制中重要的组成部分, 这些方法只有在Synchronized方法或Synchronized代码块中才能使用 否者就会报java.lang.IllegalMonitorStateExceprion异常 当Synchronized方法或者Synchronized代码块中的wait() 方法被调用时,当前线程将被中断运行,并且放弃该对象锁 当例外的线程执行了某个对象notify()方法后,会唤醒在此对象等待池中的某个线程使之成为可运行的(就绪状态)线程。 notifuAll()方法会唤醒所有等待这个对象的线程使之成为可运行的线程。 2.下面通过一个比较经典的问题来讲解着两个方法: 问题描述:生产者将产品交给店员,,而消费者从店员处取走产品,店员一次只能持有固定数量的产品,如果生产者生产了过多的产品, 店员会叫生产者等一下;若果店中的有空位放产品了在通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品 再通知生产者来取走产品。这里可能出现的问题有以下两个: 生产者比消费者快时,消费者会漏掉一些数据没有取到 消费者比生产者快时,消费者会取相同的数据 3.代码如下:    1 public class ProductTest { 2 3 /** 4 * @param args 5 */ 6

java笔记六:线程间的协调

爷,独闯天下 提交于 2019-12-22 03:32:44
   昨天重新学习了 java多线程的使用 ,多线程的难点就在线程之间的协调。在《操作系统》一课中,我们学习了进程,其实多线程和多进程一样,都会涉及到多个进程或者线程对某一资源共享访问的问题,当多个线程都需要修改这个资源的时候就会出现线程安全问题。   比如说在银行开个账户会有一个存折和一张卡,如果某一天同一时间丈夫拿着存折去柜台取钱,而妻子拿着银行卡去ATM取钱。当丈夫查询余额里面有3000元,正准备取2000元,这时候妻子也到ATM里面查询也有3000,也取2000元。其实银行不可能让我们这么做,如果这样的话那我们天天取钱去了,还搞什么工作啊。其实在丈夫查询的时候已经对该账号上了锁,另外的银行卡要取钱的话必须等待该锁被释放。下面用一个程序模拟这个例子: 1 package com.sync; 2 3 public class TestSync2 implements Runnable{ 4 public BankCard bc = new BankCard(); 5 public static void main(String[] args) { 6 TestSync2 test = new TestSync2(); 7 Thread wife = new Thread(test); 8 Thread husband = new Thread(test); 9 wife

Java线程安全和锁Synchronized

倖福魔咒の 提交于 2019-12-21 23:49:14
进程与线程的概念 (1)在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程。 在未配置 OS 的系统中,程序的执行方式是顺序执行,即必须在一个程序执行完后,才允许另一个程序执行;在多道程序环境下,则允许多个程序并发执行。程序的这两种执行方式间有着显著的不同。也正是程序并发执行时的这种特征,才导致了在操作系统中引入进程的概念。 自从在 20 世纪 60 年代人们提出了进程的概念后,在 OS 中一直都是以进程作为能拥有资源和独立运行的基本单位的。直到 20 世纪 80 年代中期,人们又提出了比进程更小的能独立运行的基本单位——线程(Thread),试图用它来提高系统内程序并发执行的程度,从而可进一步提高系统的吞吐量。特别是在进入 20 世纪 90 年代后,多处理机系统得到迅速发展,线程能比进程更好地提高程序的并行执行程度,充分地发挥多处理机的优越性,因而在近几年所推出的多处理机 OS 中也都引入了线程,以改善 OS 的性能。 通过上述的大致了解,基本知道线程和进程是干什么的了,那么我们下边给进程和线程总结一下概念: (3)进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器

java 里面保留字volatile及其与synchronized的区别

て烟熏妆下的殇ゞ 提交于 2019-12-21 23:43:10
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 最近在读java并发编程相关的书籍,蚂蚁金服团队的杰作,可以好好把java并发相关的内容好好研究一下 要理解volatile和synchronized的区别,首先还是需要来理解下java的内存模型 java内存模型 java中,线程之间的通信是通过 共享内存 的方式,存储在堆中的实例域,静态域以及数组元素都可以在线程间通信。java内存模型控制一个线程对共享变量的改变何时对另一个线程可见。 线程间的共享变量存在主内存中,而对于每一个线程,都有一个私有的工作内存 。工作内存是个虚拟的概念,涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化,总之就是指线程的本地内存。存在线程本地内存中的变量值对其他线程是不可见的。 如果线程A与线程B之间如要通信的话,必须要经历下面2个步骤,如图所示: 1. 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。 2. 然后,线程B到主内存中去读取线程A之前已更新过的共享变量。 关于volatile变量 由于java的内存模型中有工作内存和主内存之分,所以可能会有两种问题: (1)线程可能在工作内存中更改变量的值,而没有及时写回到主内存,其他线程从主内存读取的数据仍然是老数据 (2)线程在工作内存中更改了变量的值,写回主内存了,但是其他线程之前也读取了这个变量的值

Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)

匆匆过客 提交于 2019-12-21 21:03:00
关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。本文探讨synchronized关键字。 synchronized关键字可以修饰方法,可以修饰代码块,但不能修饰构造器、属性等。 对synchronized(this)的一些理解 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的除synchronized(this)同步代码块以外的部分。 第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。 以上规则对其它对象锁同样适用。 上述内容参考: http:/

java static synchronized method

浪子不回头ぞ 提交于 2019-12-21 20:18:54
问题 What happens when a static synchronized method is called by two threads using different instances at the same time? Is it possible? The object lock is used for non static synchronized method but what type lock is used for static synchronized method? 回答1: It is the same as synchronizing on the Class object implementing the method, so yes, it is possible, and yes, the mechanism effectively ignores the instance fro which the method is called: class Foo { private static synchronized doSomething()