Home Database Mysql Tutorial 线程等待和释放的小麻烦(wait/notify)

线程等待和释放的小麻烦(wait/notify)

Jun 07, 2016 pm 05:45 PM
object quot thread

class ThreadA extends Thread{

  //线程同步的公共数据区

  Object oa=null;

  ThreadA(Object o){

  this.oa=o;

  }

  //线程A执行逻辑

  public void run(){

  //线程同步区域,需要申请公共数据的锁

  synchronized(oa){

  System.out.println("ThreadA is running......");

  for(int i=0;i

  System.out.println("   ThreadA value is "+i);

  if(i==50){

  try {

  //当前线程等待

  Thread.currentThread().wait();

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  }//if(i==50)

  }//for(int i)

  }

  }

  }

  /**

  *  线程B:等待线程A放弃锁,然后获得锁并执行,完成后唤醒线程A

  */

  class ThreadB extends Thread{

  //线程同步的公共数据区

  Object ob=null;

  ThreadB(Object o){

  this.ob=o;

  }

  //线程B执行逻辑

  public void run(){

  //线程同步区域,需要申请公共数据的锁

  synchronized(ob){

  System.out.println("ThreadB is running......");

  for(int i=0;i

  System.out.println("   ThreadB value is "+i);

  }

  

  //唤醒等待的线程

  notify();

  }

  }

  }

  //测试

  public class ThreadTest {

  public static void main(String[] args){

  Object lock=new Object(); //公共数据区

  ThreadA threada=new ThreadA(lock);

  ThreadB threadb=new ThreadB(lock);

  threada.start(); //线程A执行

  threadb.start(); //线程B执行

  }

  }       程序很简单,就是让线程A,B交替打印。但是运行的时候会抛出两个异常:

  Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread not owner

  Exception in thread "Thread-1" java.lang.IllegalMonitorStateException: current thread not owner

  问题就处在ThreadA中的Thread.currentThread().wait(); 和ThreadB中的notify();上。

  初学者理解wait()的时候都认为是将当前线程阻塞,所以Thread.currentThread().wairt();视乎很有道理。但是不知道大家有没有发现,在JDK类库中wait()和notify()方法并不是Thread类的,而是Object()中的。我们仔细看看wait方法的JDK文档:

  public final void wait() throws InterruptedException

  Object (Java 2 Platform SE 6)

  

  在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。 换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。

  当前线程必须拥有此 对象监视器 。该线程发布对此监视器的所有权并等待 ,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。 然后该线程将等到重新获得对监视器的所有权后才能继续执行。

  对于某一个参数的版本,实现中断和虚假唤醒是可能的,而且此方法应始终在循环中使用:

  synchronized (obj) {

  while ()

  obj.wait();

  // Perform action appropriate to condition

  }

  此方法只应由作为此对象监视器的所有者的线程来调用。

  抛出: IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。

  InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。

  看完JDK文档以后,很显然,只要把开始的程序中Thread.currentThread().wait();改成oa.wait() 。 notify();改成 ob.notify()就没有问题了。

  也就是说,只能通过同步块obj来调用wait/notify方法 ,而不能通过想当然的线程调用这两个方法。至于为什么是这样,我有一种想法,大家可以一起讨论一下:

  首先,我们都知道JVM会给每一个对象都分配唯一的一把锁。这把锁是在对象中的。

  然后,当Thread-0线程获得了这把锁后,应该是在对象中的锁内记录下当前占有自己的线程号,并把自己设置为已被占用。那么当Thread-0需要放弃锁的时候,锁对象会吧 Thread-0放入到锁的等待队列中 。而这一切和Thread-0是没有任何关系的。自然也轮不到Thread-0对象来调用某个方法来改变另一个对象中的锁(这一点也说不通,我自己的锁凭什么让你来改)。

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What are the differences between Runnable and Thread in Java? What are the differences between Runnable and Thread in Java? May 07, 2023 pm 05:19 PM

There are two ways to implement multi-threading in Java, one is to inherit the Thread class, and the other is to implement the Runnable interface; the Thread class is defined in the java.lang package. As long as a class inherits the Thread class and overrides the run() method in this class, it can implement multi-threaded operations. However, a class can only inherit one parent class, which is a limitation of this method. Let’s look at an example: packageorg.thread.demo;classMyThreadextendsThread{privateStringname;publicMyThread(Stringname){super();this

php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 Jun 13, 2016 am 10:23 AM

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code

What are the methods of converting java Object to byte and byte to Object? What are the methods of converting java Object to byte and byte to Object? Apr 20, 2023 am 11:37 AM

Object to byte and byte to Object Today we will realize how to convert from Object to byte and how to convert from byte to Object. First, define a class student: packagecom.byteToObject;importjava.io.Serializable;publicclassstudentimplementsSerializable{privateintsid;privateStringname;publicintgetSid(){returnsid;}publicvoidsetSid(in

How to use methods in Java Object class How to use methods in Java Object class Apr 18, 2023 pm 06:13 PM

1. Introduction to the Object class Object is a class provided by Java by default. Except for the Object class, all classes in Java have inheritance relationships. By default, it will inherit the Object parent class. That is, objects of all classes can be received using the reference of Object. Example: Use Object to receive objects of all classes classPerson{}classStudent{}publicclassTest{publicstaticvoidmain(String[]args){function(newPerson());function(newStudent());}public

How does Thread generate an interface in java? How does Thread generate an interface in java? May 17, 2023 pm 12:49 PM

In java, when it comes to threads, Thread is essential. A thread is a lighter scheduled executor than a process. Why use threads? By using threads, you can separate resource allocation and execution scheduling in operating system processes. Each thread can not only share process resources (memory address, file I/O, etc.), but can also be scheduled independently (thread is the basic unit of CPU scheduling). Note 1. Thread is the most important class for making threads, and the word itself also represents thread. 2. The Thread class implements the Runnable interface. Instance publicclassThreadDemoextendsThread{publicvoidrun(){for(inti=0

Start a new thread using java's Thread.start() function Start a new thread using java's Thread.start() function Jul 24, 2023 pm 11:01 PM

Use Java's Thread.start() function to start a new thread. In Java, we can use multi-threading to execute multiple tasks concurrently. Java provides the Thread class to create and manage threads. The start() function in the Thread class is used to start a new thread and execute the code in the run() method of the thread. Code example: publicclassMyThreadextendsThread{@Overr

PHP Notice: Trying to get property of non-object solution PHP Notice: Trying to get property of non-object solution Jun 24, 2023 pm 09:34 PM

PHPNotice: Tryingtogetpropertyofnon-object Solution When you are developing in PHP, you may encounter this error message: "Notice: Tryingtogetpropertyofnon-object." This error message is usually due to you using an uninitialized object, or It's because your object has lost its reference in a certain piece of code and cannot access the properties correctly.

Solution to PHP Notice: Trying to get property of non-object Solution to PHP Notice: Trying to get property of non-object Jun 22, 2023 pm 02:43 PM

Solution to PHPNotice: Tryingtogetpropertyofnon-object In the process of writing code in PHP, we may encounter the error message "Tryingtogetpropertyofnon-object". This error message usually occurs because we are trying to access a non-existent object property, causing an error in the code. This error message usually appears in the following situations: The object does not exist

See all articles