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可以在任何地方使用

synchronized(x){
	try {  
		x.wait();或者x.notify()
        } catch (InterruptedException e) {  
			e.printStackTrace();  
        }  
}
注意:对象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()函数,否则不能保证其顺序性,比如消费者生产都模型。

package com.wmz.helloworld;
import java.util.Random;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Demo extends android.app.Activity {
	private class Token {
		private String flag;
		public Token() {
			setFlag(null);
		}
		public void setFlag(String flag) {
			this.flag = flag;
		}
		public String getFlag() {
			return flag;
		}
	}
	private Token token = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.demo);
		Button btn = (Button) findViewById(R.id.button1);
		token = new Token();
		if(token.getFlag() ==null)
			Log.v("A","the token flag value is null");
		else
			Log.v("A","the token flag value is"+token.getFlag());
		btn.setOnClickListener(new OnClickListener() {			
			public void onClick(View v) {
				// TODO Auto-generated method stub
				WorkThread workthread = new WorkThread();
				workthread.start();	
				Random r=new Random();
				for (int i = 0;i<10; i++) {
					try {						
						Thread.sleep((r.nextInt(9)+1)*1000);		//增加不确定性,至少睡眠1秒
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					synchronized (token) {
						token.setFlag("wangmz"+Integer.toString(i));
						token.notifyAll();
						Log.v("Main",Integer.toString(i));
					}					
				}
			}
		});		
	}


	private class WorkThread extends Thread {
		@Override
		public void run() {
			Random r=new Random();
			while (true) {				
//				try {
//					Thread.sleep((r.nextInt()+1)*1000);//可能在sleep的时候其他线程执行notify()。但此时对这个线程不起作用。所以结果不会按顺序出现
//				} catch (InterruptedException e1) {
//					e1.printStackTrace();
//				}
				synchronized (token) {
						try {
							token.wait();
							Log.v("Main", "the value is " + token.getFlag());
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
				}
				Log.v("work","while!!");
			}
		}
	}
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值