zoukankan      html  css  js  c++  java
  • JavaSE——线程通信

    线程通信:

      如果线程A和线程B持有同一个MyObject类的对象object,这两个线程会去调用不同的方法,但是它们是同步执行的,比如:线程B需要等待线程A执行完了methodA()方法之后,它才能执行methodB()方法。这样,线程A和线程B就实现了 通信。

    线程通信中要用到的方法:wait()方法:

      执行同步锁(obj对象)的该方法的线程进入堵塞状态,会释放对象的锁,java虚拟机把该线程放到该对象的等待池中,该线程如果要再次执行,则需要其他线程将它唤醒。

     1 package tongxin;
     2 
     3 public class MyThreadA extends Thread {
     4     private Object obj;
     5     public MyThreadA(String name,Object obj){
     6         
     7         super(name);
     8         this.obj = obj;
     9         
    10     }
    11     public void run(){
    12         synchronized(obj){  //设置obj为同步锁
    13 
    14             for(int i = 0;i<10;i++){
    15                 System.out.println(Thread.currentThread().getName()+"---"+i);
    16                 
    17                 if(i == 5){
    18                     try {
    19                         obj.wait();
    20                     } catch (InterruptedException e) {
    21                         // TODO Auto-generated catch block
    22                         e.printStackTrace();
    23                     }
    24                     try {
    25                         sleep(100);
    26                     } catch (InterruptedException e) {
    27                         // TODO Auto-generated catch block
    28                         e.printStackTrace();
    29                     }
    30                 }
    31             }
    32         }
    33     }
    34 
    35 }
     1 package tongxin;
     2 
     3 public class Demo01 {
     4 
     5     public static void main(String[] args) {
     6         // TODO Auto-generated method stub
     7         
     8         Object obj = new Object();
     9         MyThreadA mt1 = new MyThreadA("A",obj);
    10         mt1.start();
    11 
    12     }
    13 
    14 }

     output:

    1 A---0
    2 A---1
    3 A---2
    4 A---3
    5 A---4
    6 A---5

    当i = 5时,执行了同步锁的wait()方法,然后线程A将同步锁释放进入堵塞状态,如果A线程还有恢复运行,则需要另一个持相同同步锁的线程将其唤醒。

    唤醒线程的方法:notifi()

      另一个线程在运行过程中执行了同步锁的notifi方法,  会唤醒在对象的等待池中等待的一个线程(随机选择),java虚拟机会随机选择一个线程转到对象的锁池中。

      注意一个线程要去唤醒另一个执行了wait()方法进入堵塞状态的线程,则其要去执行同一个同步锁的notifi()方法。

      假如有一个房间,A进去之后把门锁上,A在房间里睡着了,B要把A叫醒,就要用锁(同步锁)上的钥匙把门开开。A与B用的是同一把锁,只不过A是在锁门(wait()方法),B是在开门(notifi()方法)。

     1 package tongxin;
     2 
     3 public class MyThreadB extends Thread {
     4     private Object obj;
     5     public MyThreadB(String name,Object obj){
     6         
     7         super(name);
     8         this.obj = obj;
     9         
    10     }
    11     public void run(){
    12         synchronized(obj){  //设置obj为同步锁
    13 
    14             for(int i = 0;i<10;i++){
    15                 System.out.println(Thread.currentThread().getName()+"---"+i);
    16                 
    17                 if(i == 2){
    18                     obj.notify();
    19                     try {
    20                         sleep(100);
    21                     } catch (InterruptedException e) {
    22                         // TODO Auto-generated catch block
    23                         e.printStackTrace();
    24                     }
    25                 }
    26             }
    27         }
    28     }
    29 
    30 
    31 }
     1 package tongxin;
     2 
     3 public class Demo01 {
     4 
     5     public static void main(String[] args) {
     6         // TODO Auto-generated method stub
     7         
     8         Object obj = new Object();
     9         MyThreadA mt1 = new MyThreadA("A",obj);
    10         MyThreadB mt2 = new MyThreadB("B",obj);
    11         mt1.start();
    12         mt2.start();
    13         
    14 
    15     }
    16 
    17 }

     output:

    A---0
    A---1
    A---2
    A---3
    A---4
    A---5
    B---0
    B---1
    B---2
    B---3
    B---4
    B---5
    B---6
    B---7
    B---8
    B---9
    A---6
    A---7
    A---8
    A---9

    创建一个新的线程对象B来唤醒A线程,运行过程中,i = 2时,B唤醒A线程将其转到对象的锁池中,但此时由于B持有同步锁所以B线程继续运行,运行结束后释放同步锁,此时A获取到同步锁恢复运行。

    notifyAll()方法:

    该方法会唤醒在这个对象锁池中的所有线程。

    如有不对之处还望指正,谢谢。

  • 相关阅读:
    Android笔记(六十六) android中的动画——XML文件定义属性动画
    Android笔记(六十五) android中的动画——属性动画(propertyanimation)
    python函数参数默认值及重要警告
    Python 列表
    Python数学运算入门把Python当作计算器
    Python 的非正式介绍
    python中为什么 if/while/def/class语句需要冒号?
    为什么Python在列表和元组的末尾允许使用逗号?
    现实世界中的 Python
    Python常见问题
  • 原文地址:https://www.cnblogs.com/linlin0/p/6161006.html
Copyright © 2011-2022 走看看