当前位置: 移动技术网 > IT编程>开发语言>Java > Java多线程中线程间的通信实例详解

Java多线程中线程间的通信实例详解

2019年07月22日  | 移动技术网IT编程  | 我要评论

java多线程中线程间的通信

一、使用while方式来实现线程之间的通信

package com.ietree.multithread.sync;

import java.util.arraylist;
import java.util.list;

public class mylist {
  
  private volatile static list list = new arraylist();

  public void add() {
    list.add("apple");
  }

  public int size() {
    return list.size();
  }

  public static void main(string[] args) {

    final mylist list1 = new mylist();

    thread t1 = new thread(new runnable() {
      @override
      public void run() {
        try {
          for (int i = 0; i < 10; i++) {
            list1.add();
            system.out.println("当前线程:" + thread.currentthread().getname() + "添加了一个元素..");
            thread.sleep(500);
          }
        } catch (interruptedexception e) {
          e.printstacktrace();
        }
      }
    }, "t1");

    thread t2 = new thread(new runnable() {
      @override
      public void run() {
        while (true) {
          if (list1.size() == 5) {
            system.out.println("当前线程收到通知:" + thread.currentthread().getname() + " list size = 5 线程停止..");
            throw new runtimeexception();
          }
        }
      }
    }, "t2");

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

程序输出:

当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
exception in thread "t2" 当前线程收到通知:t2 list size = 5 线程停止..
java.lang.runtimeexception
  at com.ietree.multithread.sync.mylist$2.run(mylist.java:43)
  at java.lang.thread.run(unknown source)
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..

理解:线程thread2不停地通过while语句检测这个条件(list.size()==5)是否成立 ,从而实现了线程间的通信。但是这种方式会浪费cpu资源。

二、wait notfiy 方法实现多线程中线程之间的通信

使用这种方式实现线程通信需要注意:wait和notify必须配合synchronized关键字使用,wait方法释放锁,notify方法不释放锁。并且在这个例子中必须是thread2先执行才可以。

package com.ietree.multithread.sync;

import java.util.arraylist;
import java.util.list;

public class listadd3 {
  private volatile static list list = new arraylist();

  public void add() {
    list.add("apple");
  }

  public int size() {
    return list.size();
  }

  public static void main(string[] args) {

    final listadd2 list2 = new listadd2();

    // 1 实例化出来一个 lock
    // 当使用wait 和 notify 的时候 , 一定要配合着synchronized关键字去使用
    final object lock = new object();

    thread t1 = new thread(new runnable() {
      @override
      public void run() {
        try {
          synchronized (lock) {
            for (int i = 0; i < 10; i++) {
              list2.add();
              system.out.println("当前线程:" + thread.currentthread().getname() + "添加了一个元素..");
              thread.sleep(500);
              if (list2.size() == 5) {
                system.out.println("已经发出通知..");
                //不释放锁,遇到size=5时还是继续执行
                lock.notify();
              }
            }
          }
        } catch (interruptedexception e) {
          e.printstacktrace();
        }

      }
    }, "t1");

    thread t2 = new thread(new runnable() {
      @override
      public void run() {
        synchronized (lock) {
          if (list2.size() != 5) {
            try {
              //释放锁,让其他线程执行
              lock.wait();
            } catch (interruptedexception e) {
              e.printstacktrace();
            }
          }
          system.out.println("当前线程:" + thread.currentthread().getname() + "收到通知线程停止..");
          throw new runtimeexception();
        }
      }
    }, "t2");

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

  }
}

程序输出:

当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
已经发出通知..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t2收到通知线程停止..
exception in thread "t2" java.lang.runtimeexception
  at com.ietree.multithread.sync.listadd3$2.run(listadd3.java:59)
  at java.lang.thread.run(unknown source)

三、使用countdownlatch类来实现多线程中线程之间的实时通信

package com.ietree.multithread.sync;

import java.util.arraylist;
import java.util.list;
import java.util.concurrent.countdownlatch;

public class listadd2 {
  private volatile static list list = new arraylist();

  public void add() {
    list.add("apple");
  }

  public int size() {
    return list.size();
  }

  public static void main(string[] args) {

    final listadd2 list2 = new listadd2();

    final countdownlatch countdownlatch = new countdownlatch(1);

    thread t1 = new thread(new runnable() {
      @override
      public void run() {
        try {
          for (int i = 0; i < 10; i++) {
            list2.add();
            system.out.println("当前线程:" + thread.currentthread().getname() + "添加了一个元素..");
            thread.sleep(500);
            if (list2.size() == 5) {
              system.out.println("已经发出通知..");
              countdownlatch.countdown();
            }
          }
          // }
        } catch (interruptedexception e) {
          e.printstacktrace();
        }

      }
    }, "t1");

    thread t2 = new thread(new runnable() {
      @override
      public void run() {
        if (list2.size() != 5) {
          try {
            countdownlatch.await();
          } catch (interruptedexception e) {
            e.printstacktrace();
          }
        }
        system.out.println("当前线程:" + thread.currentthread().getname() + "收到通知线程停止..");
        throw new runtimeexception();
      }
    }, "t2");

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

  }
}

程序输出:

当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
已经发出通知..
exception in thread "t2" 当前线程:t1添加了一个元素..
当前线程:t2收到通知线程停止..
java.lang.runtimeexception
  at com.ietree.multithread.sync.listadd2$2.run(listadd2.java:56)
  at java.lang.thread.run(unknown source)
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..

 四、使用多线程模拟一个队列

package com.ietree.multithread.sync;

import java.util.linkedlist;
import java.util.concurrent.timeunit;
import java.util.concurrent.atomic.atomicinteger;

public class myqueue {

  // 1、定义一个盛装元素集合
  private linkedlist<object> list = new linkedlist<object>();

  // 2、定义一个计数器
  private atomicinteger count = new atomicinteger();

  // 3、指定上限和下限
  private final int minsize = 0;
  private final int maxsize;

  // 4、构造方法初始化大小
  public myqueue(int size) {
    this.maxsize = size;
  }

  // 5、初始化一个对象用于加锁
  private object lock = new object();

  // put(anobject): 把anobject加到blockingqueue里,如果blockqueue没有空间,则调用此方法的线程被阻断,直到blockingqueue里面有空间再继续.
  public void put(object obj) {
    synchronized (lock) {
      if (count.get() == this.maxsize) {
        try {
          lock.wait();
        } catch (interruptedexception e) {
          e.printstacktrace();
        }
      }
      // 1、加入元素
      list.add(obj);
      // 2、计数器累加
      count.incrementandget();
      // 3、通知(唤醒)另外一个线程
      lock.notify();
      system.out.println("新加入的元素为:" + obj);
    }
  }

  // take: 取走blockingqueue里排在首位的对象,若blockingqueue为空,阻断进入等待状态直到blockingqueue有新的数据被加入.
  public object take() {
    object ret = null;
    synchronized (lock) {
      while (count.get() == this.minsize) {
        try {
          lock.wait();
        } catch (interruptedexception e) {
          e.printstacktrace();
        }
      }
      // 1、做移除元素操作
      ret = list.removefirst();
      // 2、计数器作递减操作
      count.decrementandget();
      // 3、唤醒另外一个操作
      lock.notify();
    }

    return ret;
  }

  // 获取长度
  public int getsize() {
    return this.count.get();
  }

  public static void main(string[] args) {

    final myqueue mq = new myqueue(5);
    mq.put("a");
    mq.put("b");
    mq.put("c");
    mq.put("d");
    mq.put("e");

    system.out.println("当前容器的长度:" + mq.getsize());

    thread t1 = new thread(new runnable() {
      @override
      public void run() {
        mq.put("f");
        mq.put("g");
      }
    }, "t1");

    t1.start();

    thread t2 = new thread(new runnable() {
      @override
      public void run() {
        object o1 = mq.take();
        system.out.println("移除的元素为:" + o1);
        object o2 = mq.take();
        system.out.println("移除的元素为:" + o2);
      }
    }, "t2");

    try {
      timeunit.seconds.sleep(2);
    } catch (interruptedexception e) {
      e.printstacktrace();
    }

    t2.start();
  }
}

程序输出:

新加入的元素为:a
新加入的元素为:b
新加入的元素为:c
新加入的元素为:d
新加入的元素为:e
当前容器的长度:5
移除的元素为:a
移除的元素为:b
新加入的元素为:f
新加入的元素为:g

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网