java synchronized wait

在多个线程要互斥访问数据,
但线程间需要同步时——例如任务分多个阶段,特定线程负责特定阶段的情况,
经常合作使用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

 

时间: 2025-01-18 20:33:35

java synchronized wait的相关文章

java synchronized关键字的用法_java

0.先导的问题代码     下面的代码演示了一个计数器,两个线程同时对i进行累加的操作,各执行1000000次.我们期望的结果肯定是i=2000000.但是我们多次执行以后,会发现i的值永远小于2000000.这是因为,两个线程同时对i进行写入的时候,其中一个线程的结果会覆盖另外一个. public class AccountingSync implements Runnable { static int i = 0; public void increase() { i++; } @Overr

java synchronized没有起作用

问题描述 java synchronized没有起作用 package com.wxb.syn; class Semaphore{} public class BalanceTest extends Thread{ public static int balance = 100; public Semaphore semp = new Semaphore(); public void run() { synchronized(this){// System.out.println(""

java synchronized详解

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.      一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块.      二.然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(th

Java synchronized 锁问题

问题描述 一个类中有很多个函数都包含一个同步锁,锁都是同一个对象method1(){synchronized(obj){}}method2(){synchronized(obj){}}method3()...该锁的class跑在一个服务进程里,有很多客户端访问该进程,在一个客户端中发现总是阻塞在method()函数里在等待这个锁被释放,我想知道该锁此时被谁占用了,其他方法中哪个方法在同步锁的块中做耗时操作?请问有什么方法吗最笨的方法是打出每个同步锁方法的时间来判断,但是如果有方法大家时间都差不多

Java synchronized 介绍

我们知道Java API提供了丰富的多线程机制,但是要想多线程机制能够正常运转,需要采取一些措施来防止多个线程访问相同的资源.为防止出现这样的冲突,只需在线程使用一个资源时为其加锁即可.访问资源的第一个线程加上锁以后,其他线程便不能再使用那个资源,除非被解锁. 而在java中,对这种特殊的资源-- 对象中的内存-- Java 提供了内建的机制来防止它们的冲突.用Java中的Synchronized关键字来标记一个方法或者一个代码块就可以实现资源的同步. synchronized主要使用在多线程环

java synchronized用法详解_java

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 二.然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块.

java synchronized关键字的用法

在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识.   java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁.线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁.获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法.   java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,

java synchronized wait notify 生产者消费者死锁问题求解

问题描述 //仓库类publicclassWareHouse{//存货物的容器List<String>store=newArrayList<String>();publicWareHouse(){}//存货物的动作publicvoidstock(Stringproduct){synchronized(this){//往仓库中存一个货物System.out.println("卖家已经存入了货物:"+product+",通知等待得购买者");st

JAVA synchronized 线程经典 生产者消费者 两个完全不同的实现的方式

package sell_ticket; public class ThreadTicket { public static void main(String[] args) { MyThread m = new MyThread(); Thread t1 = new Thread(m); Thread t2 = new Thread(m); Thread t3 = new Thread(m); t1.start(); t2.start(); t3.start(); } } class MyTh