java多线程之线程通信

2022-03-24 15:41:45 浏览数 (1)

线程通信的例子 使用两个线程打印 1-100。 线程1,线程2交替打印

  • 涉及的三个方法:
  • wait():一旦执行此方法当前线程进入阻塞状态 ,并释放同步监视器(锁)。
  • notify():一旦执行此方法就会唤醒被wait的线程 如果有多个线程被wait 会唤醒优先级高的那一个。
  • notifyAll():一旦执行此方法会唤醒所有被wait的现线程。
代码语言:javascript复制
 class Number implements Runnable{
     private int number=1;
    @Override
    public void run() {
       while (true){
           synchronized (this){

           if(number<=100){
               System.out.println(Thread.currentThread().getName() ":" number);
               number  ;
           }else{
               break;
           }
           }
       }
    }
}
public class CommunicationTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

        t1.setName("线程一");
        t2.setName("线程二");

        t1.start();
        t2.start();
    }
}

此时都是由一个线程执行 并没有交替运行 我们需要加入wait 和notify方法 wait():一旦执行此方法当前线程进入阻塞状态 ,并释放同步监视器(锁)。 notify():一旦执行此方法就会唤醒被wait的线程 如果有多个线程被wait 会唤醒优先级高的那一个。 notifyAll():一旦执行此方法会唤醒所有被wait的现线程。

代码语言:javascript复制
class Number implements Runnable{
     private int number=1;
    @Override
    public void run() {
       while (true){
           synchronized (this){

               notify();

           if(number<=100){
               System.out.println(Thread.currentThread().getName() ":" number);
               number  ;

               try {
                 //使得调用如下wait方法的线程进入阻塞状态
                   wait();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }else{
               break;
           }
           }
       }
    }
}
public class CommunicationTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

        t1.setName("线程一");
        t2.setName("线程二");

        t1.start();
        t2.start();
    }
}

说明: 1.wait,notify,notifyAll这三个方法必须使用在同步代码块或同步方法中。 2.wait,notify,notifyAll这三个方法的调用者必须是同步代码块或同步方法中的同步监视器。 否则会出现异常。

例:我们更改锁的this对象为object

代码语言:javascript复制
class Number implements Runnable{
     private int number=1;
      Object obj=new Object();
    @Override
    public void run() {
       while (true){
           synchronized (obj){

               notify();

           if(number<=100){
               System.out.println(Thread.currentThread().getName() ":" number);
               number  ;

               try {
                 //使得调用如下wait方法的线程进入阻塞状态
                   wait();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }else{
               break;
           }
           }
       }
    }
}

会抛出异常

因为wait等方法是锁对象调用的所以必须把调用方法的对象改为obj

代码语言:javascript复制
class Number implements Runnable{
     private int number=1;
      Object obj=new Object();
    @Override
    public void run() {
       while (true){
           synchronized (obj){

               obj.notify();

           if(number<=100){
               System.out.println(Thread.currentThread().getName() ":" number);
               number  ;

               try {
                 //使得调用如下wait方法的线程进入阻塞状态
                   obj.wait();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }else{
               break;
           }
           }
       }
    }
}

3.wait,notify,notifyAll这三个方法是定义在java.lang.object中的

0 人点赞