• android 线程 wait notify


    线程状态

    Thread States - State Diagram


    1.程序通过Thread t = new Thread(),调用t.start()启动一个线程,使该线程进入可运行(Runnable)的状态。
    2.由JVM的决定去调度(Scheduler) 在可运行状态(Runnable)下的线程,使该线程处于运行 (Running) 状态,由于JVM的调度会出现不可控性,即不是优先级高的先被调用,可能先调用,也可能后调用的的情况。运行状态(Running)下,调用礼让 yield()方法,可以使线程回到可运行状态(Runnable)下,再次JVM的调度(并不依赖优先级)。
    3.线程在Running的过程中可能会遇到 ①睡眠(sleeping)、②等待(waiting)、③阻塞(Blocked) 
    ①.调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
    ②.调用wait(),使该线程处于等待池(wait blocked pool),直到notify()/notifyAll(),线程被唤醒被放到锁池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)
    ③.对Running状态的线程加同步锁(Synchronized)使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。
    4.线程run()运行结束或异常退出,线程到达死亡状态(Dead)


    sleep和wait的区别有:
    1,类:这两个方法来自不同的类分别是Thread和Object
    2,锁:最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
    3,域:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用

    1. synchronized(x){  
    2.     try {    
    3.         x.wait();或者x.notify()  
    4.         } catch (InterruptedException e) {    
    5.             e.printStackTrace();    
    6.         }    
    7. }  

    注意:对象x不能是基本类型,应该为可引用类型或者javabean
    4,停:其实两者都可以让线程暂停一段时间,但是本质的区别是一个线程的运行状态控制,一个是线程之间的通讯的问题
    .notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
    notifyAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

    java中对Object的wait()和nofity(),在object中有一个wai()t队列,一旦拥有该object的线程调用了该方 法,线程状态将从running 变为 waiting 。只有在其他线程调用了该object的notify(),将随机的从wait队列中挑选一个线程(或者notify()待定全部线程),将其状态从 waitting 变为 runningable。如果当前对象的wait队列没有线程,则不产生影响。

    在两个线程协同作用的场景中,至少要保用两对wait() notify()函数,否则不能保证其顺序性,比如消费者生产都模型。

    1.   
    1. package com.wmz.helloworld;  
    2. import java.util.Random;  
    3. import android.os.Bundle;  
    4. import android.util.Log;  
    5. import android.view.View;  
    6. import android.view.View.OnClickListener;  
    7. import android.widget.Button;  
    8. public class Demo extends android.app.Activity {  
    9.     private class Token {  
    10.         private String flag;  
    11.         public Token() {  
    12.             setFlag(null);  
    13.         }  
    14.         public void setFlag(String flag) {  
    15.             this.flag = flag;  
    16.         }  
    17.         public String getFlag() {  
    18.             return flag;  
    19.         }  
    20.     }  
    21.     private Token token = null;  
    22.     @Override  
    23.     protected void onCreate(Bundle savedInstanceState) {  
    24.         super.onCreate(savedInstanceState);  
    25.         setContentView(R.layout.demo);  
    26.         Button btn = (Button) findViewById(R.id.button1);  
    27.         token = new Token();  
    28.         if(token.getFlag() ==null)  
    29.             Log.v("A","the token flag value is null");  
    30.         else  
    31.             Log.v("A","the token flag value is"+token.getFlag());  
    32.         btn.setOnClickListener(new OnClickListener() {            
    33.             public void onClick(View v) {  
    34.                 // TODO Auto-generated method stub  
    35.                 WorkThread workthread = new WorkThread();  
    36.                 workthread.start();   
    37.                 Random r=new Random();  
    38.                 for (int i = 0;i<10; i++) {  
    39.                     try {                         
    40.                         Thread.sleep((r.nextInt(9)+1)*1000);        //增加不确定性,至少睡眠1秒  
    41.                     } catch (InterruptedException e) {  
    42.                         e.printStackTrace();  
    43.                     }  
    44.                     synchronized (token) {  
    45.                         token.setFlag("wangmz"+Integer.toString(i));  
    46.                         token.notifyAll();  
    47.                         Log.v("Main",Integer.toString(i));  
    48.                     }                     
    49.                 }  
    50.             }  
    51.         });       
    52.     }  
    53.   
    54.   
    55.     private class WorkThread extends Thread {  
    56.         @Override  
    57.         public void run() {  
    58.             Random r=new Random();  
    59.             while (true) {                
    60. //              try {  
    61. //                  Thread.sleep((r.nextInt()+1)*1000);//可能在sleep的时候其他线程执行notify()。但此时对这个线程不起作用。所以结果不会按顺序出现  
    62. //              } catch (InterruptedException e1) {  
    63. //                  e1.printStackTrace();  
    64. //              }  
    65.                 synchronized (token) {  
    66.                         try {  
    67.                             token.wait();  
    68.                             Log.v("Main""the value is " + token.getFlag());  
    69.                         } catch (InterruptedException e) {  
    70.                             e.printStackTrace();  
    71.                         }  
    72.                 }  
    73.                 Log.v("work","while!!");  
    74.             }  
    75.         }  
    76.     }  
    77. }  


    转:http://blog.csdn.net/mzwang123/article/details/7333885


  • 相关阅读:
    GFS读后笔记
    BigTable读后笔记
    恢复系统基础理论
    事务基础理论
    ARIES算法简介
    怎么快速构建自己的C/C++程序?——有关编译、静态链接和SCons
    lua学习笔记
    运行时动态伪造vsprintf的va_list
    11月30日站立会议
    11月29号站立会议
  • 原文地址:https://www.cnblogs.com/jiezzy/p/2658881.html
Copyright © 2020-2023  润新知