关于锁的分类 及 锁的灵活使用:

参见 http://blog.csdn.net/qaz13177_58_/article/details/21543515 

有几句话说得相当不错:

锁的分类 :

同步分为类级别和对象级别,分别对应着类锁和对象锁。类锁是每个类只有一个,如果static的方法被synchronized关键字修饰,则在这个方法被执行前必须获得类锁;对象锁类同。

唤醒的含义:

只要是在synchronied块中的代码,没有对象锁是寸步难行的。其实唤醒一个线程就是重新允许这个线程去获得对象锁并向下运行。

———— 跟我的理解相同。 呵呵

notifyAll:

虽然notifyAll是对每个wait的对象都调用一次notify,但是这个还是有顺序的,每个对象都保存这一个等待对象链,调用的顺序就是这个链的顺序。其实启动等待对象链中各个线程的也是一个线程,在具体应用的时候,需要注意一下。

 从

package test;
public class NotifyTest {
private String flag[] = { "true" }; class NotifyThread extends Thread {
public NotifyThread(String name) {
super(name);
} public void run() {
try {
sleep();// 推迟3秒钟通知
} catch (InterruptedException e) {
e.printStackTrace();
} synchronized (flag) {
flag[] = "false"; // notify并不会立即唤醒wait的进程,
// 必须等待当前同步块执行完毕!
//flag.notify(); flag.notifyAll(); // try {
// sleep(20000);// 推迟3秒钟通知
// } catch (InterruptedException e) {
// e.printStackTrace();
// } }
}
}; class WaitThread extends Thread {
public WaitThread(String name) {
super(name);
} public void run() {
synchronized (flag) {
while (flag[] != "false") {
System.out.println(getName() + " begin waiting!");
long waitTime = System.currentTimeMillis(); try {
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} waitTime = System.currentTimeMillis() - waitTime;
System.out.println("wait time :" + waitTime);
}
System.out.println(getName() + " end waiting!");
}
}
} public static void main(String[] args) throws InterruptedException {
System.out.println("Main Thread Run!");
NotifyTest test = new NotifyTest();
NotifyThread notifyThread = test.new NotifyThread("notify01");
WaitThread waitThread01 = test.new WaitThread("waiter01");
WaitThread waitThread02 = test.new WaitThread("waiter02");
WaitThread waitThread03 = test.new WaitThread("waiter03");
WaitThread waitThread04 = test.new WaitThread("waiter04");
WaitThread waitThread05 = test.new WaitThread("waiter05");
notifyThread.start();
waitThread01.start();
waitThread02.start();
waitThread03.start();
waitThread04.start();
waitThread05.start();
}
} 打印: Main Thread Run!
waiter02 begin waiting!
waiter01 begin waiting!
waiter03 begin waiting!
waiter04 begin waiting!
waiter05 begin waiting!
wait time :
waiter05 end waiting!
wait time :
waiter04 end waiting!
wait time :
waiter03 end waiting!
wait time :
waiter01 end waiting!
wait time :
waiter02 end waiting!

结果来看,应该等待对象链是一个栈,先获得对象锁的先放入栈中,notifyAll的时候反序唤醒。。———— 当然,我觉得这个,要是看到哦Object的源码就会十分清楚了吧!

写得太好了,再复制一段:

notify():

唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。

调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

notifyAll():

唤醒所有等待的线程,注意唤醒的是notify之前wait的线程,对于notify之后的wait线程是没有效果的。?? 这个可能看源码才清楚, 不过先记住这个。

 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。—— wait执行完后就不执行(下面的任何代码)了,亦即’阻塞‘的含义

通常,多线程之间需要协调工作:如果条件不满足,则等待;当条件满足时,等待该条件的线程将被唤醒。在Java中,这个机制的实现依赖于wait/notify。等待机制与锁机制是密切关联的。

例如:
  synchronized(obj) {
  while(!condition) {--------------------// 我还是不懂为什么一定要有一个while。— 懂了!完全可以没有while 。其实while可以换成if ,只是效果不一样!

            ------------------ while的意思是说,如果条件不满足,即使你唤醒了该线程也没用!它会又马上有陷入wait,如此循环,

            ------------------ if     的意思是说,不用说了吧 : 第一次不满足就wait,唤醒之后就不会再陷入。。继续执行后面的

            ------------------ 到底用哪个,当然是根据语境来判断的。 貌似while 用得多,更好用。。。
  obj.wait();
  }
  obj.doSomething();
  }
  
  当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。
  在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A :
  
  synchronized(obj) {
  condition = true;
  obj.notify();
  }

注意一点:如果要把notify和wait方法放在一起用的话,必须先调用notify后调用wait,因为如果调用完wait,该线程就已经不是currentthread了 —— 表示不懂。。

一起用是指?一个方法/代码块既有notify又有wait ? 有这样的写法吗? 奇了怪了

notify

notify并不会立即唤醒wait的进程,而是,必须等待当前同步块执行完毕!

疑问:

某对象上并没有任何锁, notify/notifyAll会报错吗? 应该不会。。

尽管讨论了很多,现在仍然有一些疑惑

notifyAll 的作用是唤醒所有 ‘等待在此对象上的线程’—— 那么,是否有一个顺序呢? 不然的话,这些线程可以同时执行?显然, 不可以,因为,‘一个时间,只能有一个线程拥有一个对象的监视器’, 就是说其他线程想执行同时执行同一同步代码块的话,是不可能的!

那么、 到底是如何“唤醒所有”的呢

java api上是:  

notifyAll

public final void notifyAll()
Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods.

The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.

This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.

继续讨论之前还是看看Thread类提供的方法吧!!!

理解Thread, 对理解线程相当关键!

发放

http://blog.sina.com.cn/s/blog_5ffe533a0101iwyl.html

http://www.360doc.com/content/12/1010/19/59141_240697086.shtml

http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html

好吧,现在确定的说一遍: 锁就是监视器,是针对某一个对象而已的。 这里的对象一般简单的java bean,可以理解为资源。

如果理解不了锁的概念,那么真是作孽,多线程的资源争用问题还如何继续理解?? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

sleep和wait的区别?

现在看来,这个已经是是否清楚了吧!

异:sleep并不会释放锁,而wait会。 __ 释放锁,意味着释放资源,依情况而定,有好处有坏处。。

sleep没有提供无参的sleep()方法。 而wait有。sleep安全? 而wait有多线程的安全问题? 没有!

wait需要在同步块(必须是synchronized, Lock都不行)中执行,sleep无需。 

同:很明显,它们都导致了线程的阻塞(广义的阻塞)、 都需要捕获异常吧

http://www.cnblogs.com/zxyl/archive/2012/06/05/2536724.html

http://www.cnblogs.com/web100/p/sleep-wait.html

yeild, Thread的方法,让一个线程从running状态变为就绪状态,cpu让给优先级更高的线程,让出的时间? 不定。。

void java.lang.Thread.interrupt()      Interrupts this thread.   ————打搅sleep睡觉专用的? 好难理解。以后再看。  

  

void java.lang.Thread.interrupt()
Interrupts this thread. Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown. If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a java.nio.channels.ClosedByInterruptException. If this thread is blocked in a java.nio.channels.Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked. If none of the previous conditions hold then this thread's interrupt status will be set. Interrupting a thread that is not alive need not have any effect.

java 锁4的更多相关文章

  1. java 锁!

    问题:如何实现死锁. 关键: 1 两个线程ta.tb 2 两个对象a.b 3 ta拥有a的锁,同时在这个锁定的过程中,需要b的锁:tb拥有b的锁,同时在这个锁定的过程中,需要a的锁: 关键的实现难点是 ...

  2. Java锁(一)之内存模型

    想要了解Java锁机制.引发的线程安全问题以及数据一致性问题,有必要了解内存模型,机理机制了解清楚了,这些问题也就应声而解了. 一.主内存和工作内存 Java内存模型分为主内存和工作内存,所有的变量都 ...

  3. Java锁的种类

    转载自:---->http://ifeve.com/java_lock_see/ Java锁的种类以及辨析锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchroniz ...

  4. JAVA 锁

    JAVA 锁 锁的概念 Java中的锁是控制资源访问的一种方式.它弥补了synchronized的可操作性不强的不足. Java的锁都实现了Lock接口.Lock结构定义了锁的基本操作. 函数 解释 ...

  5. JAVA锁的可重入性

    机制:每个锁都关联一个请求计数器和一个占有他的线程,当请求计数器为0时,这个锁可以被认为是unhled的,当一个线程请求一个unheld的锁时,JVM记录锁的拥有者,并把锁的请求计数加1,如果同一个线 ...

  6. JAVA 锁之 Synchronied

    ■ Java 锁 1. 锁的内存语义 锁可以让临界区互斥执行,还可以让释放锁的线程向同一个锁的线程发送消息 锁的释放要遵循 Happens-before 原则(锁规则:解锁必然发生在随后的加锁之前) ...

  7. java锁与监视器概念 为什么wait、notify、notifyAll定义在Object中 多线程中篇(九)

    在Java中,与线程通信相关的几个方法,是定义在Object中的,大家都知道Object是Java中所有类的超类 在Java中,所有的类都是Object,借助于一个统一的形式Object,显然在有些处 ...

  8. 自己动手写java锁

    1.LockSupport的park和unpark方法的基本使用,以及对线程中断的响应性 LockSupport是JDK中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞原语.java锁和同步器 ...

  9. Java 锁的学习

    个人学习整理,所有资料均来源于网络,非原创. 死锁的四个必要条件:互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用.请求与保持条件(Hold and wait):已经得 ...

  10. java锁——wait,notify,synchronized

    背景:这篇博客用来总结java锁相关的知识点,平时还是要自己多加练习 wait 和 notify以及notifyAll (1).方法介绍1.wait.notify以及notifyAll都是Object ...

随机推荐

  1. POCO Controller 你这么厉害,ASP.NET vNext 知道吗?

    写在前面 阅读目录: POCO 是什么? 为什么会有 POJO? POJO 的意义 POJO 与 PO.VO 的区别 POJO 的扩展 POCO VS DTO Controller 是什么? 关于 P ...

  2. SQL数据库之DQL

    初来乍到,我是一个Java行业的小学生,刚学半年. 今天老师讲了数据库的操作语句,在这里与大家分享一下我学到的知识吧,要是有不足的地方麻烦大家指出来,共同进步,共同提高! 1.数据库中的各种符号 %: ...

  3. CorelDRAW X8 如何破解激活(附国际版安装包+激活工具) 2016-12-15

    之前有位搞平面的好友“小瘦”说CDR X8无法破解,只能用X7.呃……呃……呃……好像是的 其实CDR8难激活主要在于一个点“没有离线激活了,只可以在线激活”,逆天不是专供逆向的,当然没能力去破解,这 ...

  4. Power BI官方视频(3) Power BI Desktop 8月份更新功能概述

    Power BI Desktop 8月24日发布了更新版本.现将更新内容翻译整理如下,可以根据后面提供的链接下载最新版本使用. 1.主要功能更新 1.1 数据钻取支持在线版 以前的desktop中进行 ...

  5. [C#] 简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)

    using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Wen. ...

  6. 防线修建 bzoj 2300

    防线修建(1s 512MB)defense [问题描述] 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还 ...

  7. 子类继承父类时JVM报出Error:Implicit super constructor People() is undefined for default constructor. Must define an explicit constructor

    当子类继承父类的时候,若父类没有定义带参的构造方法,则子类可以继承父类的默认构造方法 当父类中定义了带参的构造方法,子类必须显式的调用父类的构造方法 若此时,子类还想调用父类的默认构造方法,必须在父类 ...

  8. margin折叠-从子元素margin-top影响父元素引出的问题

    正在做一个手机端电商项目,顶部导航栈的布局是一个div包含一个子div,如果给在正常文档流中的子div一个垂直margin-top,神奇的现象出现了,两父子元素的边距没变,但父div跟着一起往下走了! ...

  9. BPM配置故事之案例12-触发另外流程

    还记得阿海么,对就是之前的那个采购员,他又有了些意见. 阿海:小明,你看现在的流程让大家都这么方便,能不能帮个忙让我也轻松点啊-- 小明:--你有什么麻烦,现在不是已经各个部门自己提交申请了嘛? 阿海 ...

  10. BPM配置故事之案例2-文本默认值

    Boss感觉方便了很多,然而采购部采购员阿海却还是有点意见,他跑来找小明. 阿海:现在申请都是我在提交,申请人和申请部门能不能不要每次都要填写啊,好麻烦的. 小明:没问题,这个简单. 小明在表单中把申 ...