• Java线程:线程交互


    一、基础知识

      java.lang.Object的类的三个方法:

        void notify():唤醒在此对象监视器上等待的单个线程。

        void notifyAll():唤醒在此对象监视器上等待的所有线程。

        void wait():导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法。

        void wait(long timeout):导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者是超过指定时间。

        void wait(long timeout,int nanos):导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者是其他某个线程中断当前线程,或超过某个实际时间。

    以上方法使用要点:

      必须从同步环境中调用这些方法。线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。

      以上几种方法都是Object的实例方法,与每个对象具有锁是一样的,每个对象可以有一个线程列表,它们等待来自该信号。线程通过wait()获得这个等待列表。它不再执行任何其他指令,直到调用notify()为止。如果多个线程在同一个对象上等待,则将只选择一个线程继续执行。如果没有线程等待,则不采取操作。如;

      

     1 package Thread;
     2 
     3 public class Test2 {
     4     public static void main(String[] args){
     5         ThreadB b=new ThreadB();
     6         b.start();//线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者
     7         synchronized(b){
     8             try{
     9                 System.out.println("等待对象b完成计算...>");
    10                 b.wait();//当前线程A等待
    11             }catch(InterruptedException e){
    12                 e.printStackTrace();
    13             }
    14             System.out.println("b对象计算完毕,其总和是:"+b.total);
    15         }
    16     }
    17 }    
    18 class ThreadB extends Thread{
    19     int total;
    20     public void run(){
    21         synchronized(this){
    22             for(int i=0;i<101;i++){
    23                 total+=i;
    24             }
    25             notify();//(完成计算)唤醒在此对象监视器上等待的单个线程,在本例中A被唤醒。
    26         }
    27     }
    28 }
    1 等待对象b完成计算...>
    2 b对象计算完毕,其总和是:5050

      在对象上调用wait()方法时,执行该代码的线程立刻放弃它在该对象的锁,然后调用调用notify()方法,如果线程仍然在完成同步代码,则线程移出之前不会放弃锁。因此,只要调用notify()并不意味着这时的锁变得可用。

    二、多个线程在等待一个对象锁时使用notifyAll()

      多数情况下,最好通知等待某个对象的所有线程。如果这样做,可以在对象上使用notifyAll()方法,让所有等待的线程返回到可运行状态。如:

     1 package Thread;
     2 
     3 public class Test2 extends Thread{    
     4     public static void main(String[] args){
     5         Calculator calculator=new Calculator();
     6         new Test2(calculator).start();
     7         new Test2(calculator).start();
     8         new Test2(calculator).start();
     9         calculator.start();//线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者        
    10     }
    11     Calculator calculator;
    12     public Test2(Calculator calculator){
    13         this.calculator=calculator;
    14     }
    15     public void run(){
    16         synchronized(calculator){
    17             try{
    18                 System.out.println(Thread.currentThread()+"等待计算结果...>");
    19                 calculator.wait();//当前线程A等待
    20             }catch(InterruptedException e){
    21                 e.printStackTrace();
    22             }
    23             System.out.println(Thread.currentThread()+"结果为:"+calculator.total);
    24         }        
    25     }
    26 }    
    27 class Calculator extends Thread{
    28     int total;
    29     public void run(){
    30         synchronized(this){
    31             for(int i=0;i<101;i++){
    32                 total+=i;
    33             }
    34             notifyAll();//(完成计算)唤醒在此对象监视器上等待的单个线程,在本例中A被唤醒。
    35         }
    36     }
    37 }
    View Code
    1 Thread[Thread-1,5,main]等待计算结果...>
    2 Thread[Thread-3,5,main]等待计算结果...>
    3 Thread[Thread-2,5,main]等待计算结果...>
    4 Thread[Thread-2,5,main]结果为:5050
    5 Thread[Thread-3,5,main]结果为:5050
    6 Thread[Thread-1,5,main]结果为:5050
    View Code
    当神已无能为力,那便是魔渡众生
  • 相关阅读:
    mysql 数据库备份
    半同步复制
    mysql在线热备
    mysqlxtrabackup备份
    MySQL备份与恢复
    Mysql语句类型
    MySQL的体系结构
    MySQL介绍及安装
    Shell-02-if
    Shell 脚本进阶,经典用法及其案例
  • 原文地址:https://www.cnblogs.com/liuzhongfeng/p/5080813.html
Copyright © 2020-2023  润新知