在多个线程要互斥访问数据,
但线程间需要同步时——例如任务分多个阶段,特定线程负责特定阶段的情况,
经常合作使用synchronized 和 wait()
/**
*
* 计算输出其他线程锁计算的数据
* @author
*
*/
public class Main {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();// 启动计算线程
synchronized (b) {
try {
System.out.println("等待对象b完成计算...");// 当前线程A等待
b.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("b对象计算的总和是:" + b.total);
}
}
}
public class ThreadB extends Thread {
int total; public void run() {
synchronized (this) {
for (int i = 0; i < 101; i++) {
total += i;
}
//计算操作结束
notify();//唤醒在此对象监视器上等待的单个线程,在本例中线程A被唤醒
}
}
}
synchronized(b)导致了b上开启了同步锁。也就是说
只要存在 synchronized (b) 就会等待解锁。
也就是说A里的synchronized(b) {} 就是为了防止在执行的时候B里的synchronized(this){ } 代码段同时执行。
来个时间线。
1. A: synchronized (b) {
(这时候拿到b的锁,其他同步段不能执行,在等待中)
2. try {
System.out.println("等待对象b完成计算。。。");
b.wait();
(这时候A放弃b锁,让B执行)
3. B: synchronized (this) {
for (int i = 0; i < 101; i++) {
total += i;
}
notify();
(唤醒A)
4. A:继续执行。
还可以用于方法前标示同步方法
比如:
public synchronized void methodA(){}
wait()是Object的方法,意味着所有的对象都有这个方法。
调用这个方法时表示执行这个方法的当前线程放弃执行,进入等待状态,同时放弃对象锁,其它线程就可以进入由同一个对象锁控制的同步块或同步方法。
wait()时会先释放当前线程所拥有的锁,
当从wait状态返回时,会再次获取之前的锁,之后再执行后续代码。
这点由JVM保证,可查JDK文档。
为什么wait()一定要在同步方法或同步块中调用?
这是因为wait()命令的发出者必须首先拥有锁,或者说只有手中持有锁的线程才有资格等待以交出控制权。wait()/notify()这种机制的引入本身就是为了在资源独占(表现为synchronized)的前提下合作,所以只有配合锁使用才有意义。
wait()/notify()是相互协作的,刚开始怎么想也想不明白要独占资源
现在想了一下,好像有点眉目了:
一个线程计算结果,另外一个线程等待结果,但是两个线程都要访问某个共同变量,一个线程往里放结果,另外一个线程从中取结果。上面例子的total就是共同变量。因为要访问共同变量,所以涉及到资源独占的问题,所以要加上synchronized关键字。
wait()促使当前线程放弃锁,其他等待线程可以拿到锁了
sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
http://bbs.csdn.net/topics/330005504
java synchronized wait的更多相关文章
-
Java Synchronized Blocks
From http://tutorials.jenkov.com/java-concurrency/synchronized.html By Jakob Jenkov A Java synchro ...
-
java synchronized(一)
java synchronized主要用于控制线程同步,中间有很多小的细节,知识,这里我简单的整理一下,做个记录.主要用于方法和代码块的控制 先说说方法控制 模拟银行存款和取款,创建一个Account ...
-
java synchronized使用
java synchronized 基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案.这意味着在给定时刻只允许一个任务访问该资源.这个一般通过在代码上加一条锁语句实现,因为 ...
-
Java synchronized 详解
Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ...
-
Java Synchronized 关键字
本文内容 Synchronized 关键字 示例 Synchronized 方法 内部锁(Intrinsic Locks)和 Synchronization 参考资料 下载 Demo Synchron ...
-
Java synchronized 关键字详解
Java synchronized 关键字详解 前置技能点 进程和线程的概念 线程创建方式 线程的状态状态转换 线程安全的概念 synchronized 关键字的几种用法 修饰非静态成员方法 sync ...
-
Java synchronized对象级别与类级别的同步锁
Java synchronized 关键字 可以将一个代码块或一个方法标记为同步代码块.同步代码块是指同一时间只能有一个线程执行的代码,并且执行该代码的线程持有同步锁.synchronized关键字可 ...
-
java synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
-
Java synchronized
1. 将synchronized加在方法上, 即可实现对此方法的同步 public synchronized void deposit(float amt) { float tmp = amount; ...
-
Java synchronized指南
在多线程程序中,同步修饰符用来控制对临界区代码的访问.其中一种方式是用synchronized关键字来保证代码的线程安全性.在Java中,synchronized修饰的代码块或方法不会被多个线程并发访 ...
随机推荐
-
JavaScript滚动条插件源码
这是过年的时候自己写的js滚动条插件的源码,做出的效果自己并不满意,正因为做的并不满意所以回头重新巩固和深入学习js,这个插件有如下几个不太满意的地方: 内容的过度效果,可以参阅QQ客户端最近会话列表 ...
-
(转)supertable像excel那样固定table的表头和第一列
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"/> <title> ...
-
15、C#基础整理(递归)
带输出参数的函数 输入参数相当于函数而言,相当于已经赋值了的变量,直接可用输出参数相当于定义一个没有值的变量,在函数中进行赋值,然后调用函数的时候将赋值带出函数 例: public void shuc ...
-
应用emailAutoComplete.js来自动显示邮箱后缀列表
我们经常有邮箱的人都特别清楚,在输入我们的邮箱时,会自动显示出邮箱后缀列表,这个用户体验是不错的. 操作据悉——当我们输入文字时,会自动有个邮箱后缀名的列表. 而我这边的代码是,应用jque ...
-
JS基础类型和对象,分别是按值传递还是按引用传递?
在分析这个问题之前,我们需了解什么是按值传递(call by value),什么是按引用传递(call by reference).在计算机科学里,这个部分叫求值策略(Evaluation Strat ...
-
P1045
问题 A: P1045 时间限制: 1 Sec 内存限制: 128 MB提交: 145 解决: 127[提交][状态][讨论版] 题目描述 题目很简单,给出N个数字,不改变它们的相对位置,在中间加 ...
-
背景图片蒙上一层颜色(背景图片无法用rgba调整透明度!)
方法就是在图片上面加一层DIV,将DIV的背景颜色调成rgba(0,0,0,0.3);即可
-
[HAOI2008]移动玩具 状压
发现自己只会打状压了. 233333 不需要考虑是否会被挡,所以直接dp #include<cstdio> #include<cstring> #include<iost ...
-
Linux 小知识翻译 - 「LDAP」
这次聊聊「LDAP」. LDAP是「Lightweight Directory Access Protocol」的所有,从名字上可以看出是协议的一种. LDAP是访问数据库(层次型数据库)的组件.管理 ...
-
Android的休眠与唤醒
Android 休眠(suspend),在一个打过android补丁的内核中,state_store()函数会走另外一条路,会进入到request_suspend_state()中,这个文件在earl ...