wait和sleep的区别 以及 实例演示

参考:

Java多线程中Sleep与Wait的区别  http://uule.iteye.com/blog/1106710
关于多线程的wait与sleep的区别  http://www.iteye.com/topic/414054

有关于wait和sleep的区别,请先拜读以上文章。上面已经讲的很清楚了。

这里我主要根据自己的理解,在实例中运用wait和sleep,以加深对两者之间一个关键区别的理解。(wait会释放对象锁,而sleep则不会释放对象锁。)

实例主要流程:

Wait:

Sync_Wait 线程运行到i=20的时候,调用wait等待。此时mObject对象锁已经释放,Sync_Wait_Normal开始运行。

当Sync_Wait_Normal运行到i=50时,调用mObject.notify();唤醒了Sync_Wait。但由于此时,Sync_Wait无法得到mObject对象锁而无法立即运行。

等到Sync_Wait_Normal运行到i=80时,调用wait,Sync_Wait_Normal开始进行线程等待,并释放mObject对象锁。

这时,Sync_Wait 进行运行(从i=21开始)。当Sync_Wait 运行到i=50时,调用mObject.notify();唤醒了Sync_Wait_Normal。但由于此时,Sync_Wait_Normal无法得到mObject对象锁而无法立即运行。所以,一直到Sync_Wait运行到i=99,也就是Sync_Wait运行结束后,释放mObject对象锁。这个时候,Sync_Wait_Normal才继续运行到最后。

Sleep:

Sync_Sleep线程运行到i=20时,调用Thread.sleep,使得Sync_Sleep休眠2秒钟。但由于此时sleep并没有释放mObject对象锁。因此,Sync_Sleep_Normal此时也无法获得mObject对象锁而运行。等到Sync_Sleep因为sleep的时间过来,自己醒来,并运行结束后,Sync_Sleep_Normal才从头开始运行,一直到结束。

所以,整个过程就会使这样的:Sync_Sleep运行到i=20,在此等待2秒(会出现停顿2s现象)。接着继续运行到i=99,Sync_Sleep运行完成并结束,释放mObject对象锁。接着,Sync_Sleep_Normal获得mObject对象锁,从头开始运行,一直到结束。

实例源码下载:http://download.csdn.net/detail/yang_hui1986527/4429503

MainActivity.java

package com.snowdream.demo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {

	private static final int MSG_CLEAR = 0;
	private static final int MSG_UPDATE = 1;

	private final Object mObject = new Object();
	private final String tag = "MainActivity";
	ExecutorService pool = null; 

	private static TextView mTextView = null;

	private static Handler mHandler = new Handler(){
		public void handleMessage(Message msg){
			switch (msg.what) {
			case MSG_CLEAR:
				mTextView.setText("");
				break;
			case MSG_UPDATE:
				String str = (String)msg.obj;
				if (!TextUtils.isEmpty(str)) {
					mTextView.append(str);
					mTextView.append("\n");
				}
				break;
			default:
				break;
			}
		};
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initData();
	}

	private void initView() {
		mTextView = (TextView)findViewById(R.id.textView1);
	}

	private void initData() {
		pool = Executors.newFixedThreadPool(2);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		pool.shutdown();
	}

	public void OnButton1Click(View view) {
		int id = view.getId();
		switch (id) {
		case R.id.button1:
			mHandler.sendMessage(mHandler.obtainMessage(MSG_CLEAR));

			Sync_Wait sync_Wait = new Sync_Wait();
			Sync_Wait_Normal sync_Wait_Normal = new Sync_Wait_Normal();
			pool.execute(sync_Wait);
			pool.execute(sync_Wait_Normal);
			break;
		case R.id.button2:
			mHandler.sendMessage(mHandler.obtainMessage(MSG_CLEAR));

			Sync_Sleep sync_Sleep  = new Sync_Sleep();
			Sync_Sleep_Normal sync_Sleep_Normal = new Sync_Sleep_Normal();
			pool.execute(sync_Sleep);
			pool.execute(sync_Sleep_Normal);
			break;
		default:
			break;
		}
	}

	public class Sync_Wait implements Runnable {
		public void run() {
			synchronized(mObject){
				for (int i = 0; i < 100; i++) {
					Log.i(tag, "Sync_Wait: "+ i);

					mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE, "Sync_Wait: "+ i));

					if (20 == i) {
						try {
							mObject.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

					if (50 == i) {
						mObject.notify();
					}

				}
			}
		}
	} 

	public class Sync_Sleep implements Runnable {
		public void run() {
			synchronized(mObject){
				for (int i = 0; i < 100; i++) {
					Log.i(tag, "Sync_Sleep_Normal: "+ i);

					mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE,  "Sync1_Sleep: "+ i));

					if (20 == i) {
						try {
							Thread.sleep(2000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}
	} 

	public class Sync_Sleep_Normal implements Runnable {
		public void run() {
			synchronized(mObject){
				for (int i = 0; i < 100; i++) {
					Log.i(tag, "Sync_Sleep_Normal: "+ i);

					mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE, "Sync_Sleep_Normal: "+ i));
				}
			}
		}
	} 

	public class Sync_Wait_Normal implements Runnable {
		public void run() {
			synchronized(mObject){
				for (int i = 0; i < 100; i++) {
					Log.i(tag, "Sync_Normal: "+ i);

					mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE, "Sync_Wait_Normal: "+ i));

					if (50 == i) {
						mObject.notify();
					}

					if (80 == i) {
						try {
							mObject.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

				}
			}
		}
	} 

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true" >

        <Button
            android:id="@+id/button1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:onClick="OnButton1Click"
            android:text="Wait" />

        <Button
            android:id="@+id/button2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:onClick="OnButton1Click"
            android:text="Sleep" />

    </LinearLayout>

    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/linearLayout1"
        android:layout_toLeftOf="@+id/textView1" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="@dimen/padding_small"
            tools:context=".MainActivity" />
    </ScrollView>

</RelativeLayout>

效果预览:

时间: 2024-10-26 16:24:08

wait和sleep的区别 以及 实例演示的相关文章

Delphi实例演示Rect、Bounds生成TRect的区别_Delphi

本文以实例演示Rect.Bounds生成TRect的区别,实例代码如下: unitUnit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Button1: TButton; RadioGroup1: TRadioGroup; procedure Ra

javascript中checkbox使用方法简单实例演示_javascript技巧

演示一个小小的例子:在购物车里面,我们能够勾选自己所选的商品,然后能够显示出相应的价格.1.首先显示出相应的界面:   相关代码: <body> 商品列表:<br/> 笔记本电脑<input type="checkbox" name="mm" value="3000" onclick="chose(this)" />3000 台式机<input type="checkbox&

JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口

JAVA之旅(十二)--Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持 一.Thread 如何在自定义的代码中,自定义一个线程呢? 我们查看API文档,我们要启动一个线程,先实现一个子类, package com.lgl.hellojava; public class MyThread extends Thread { @Override public void run()

网页最简短的拖动对象代码实例演示

对象|网页 以前在网上看到的最简单的拖动对象的代码,忘记作者叫什么了.原始代码在IE下有些小问题,并且声明了文档类型为xhtml 1.0后,在FF等非IE浏览器下无效,对其进行了改进,现在已经可兼容:IE.Firefox.Opera ... 以下代码只是演示原理,具体应用请结合你自己的实际需求进行修改.  <!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/T

PHP和MySQL存储过程的实例演示

以下的文章主要是向大家介绍的是PHP和MySQL存储过程的实例演示,我前两天在相关网站看见PHP和MySQL存储过程的实例演示的资料,觉得挺好,就拿出来供大家分享.希望在大家今后的学习中会有所帮助.   PHP与MySQL存储过程 实例一:无参的存储过程     $conn = MySQL_connect('localhost','root','root') or die ("数据连接错误!!!"); MySQL_select_db('test',$conn); $sql = &quo

ADO.NET详细研究(四)--实例演示DataReader基本操作

ado 前面的文章地址: http://dev.csdn.net/develop/article/26/26246.shtm http://dev.csdn.net/develop/article/26/26480.shtm http://dev.csdn.net/develop/article/26/26481.shtm 这次我们用实例演示DataReader的基本应用,当然同时包含Command以及Connection的基本操作.通过这个实例的学习我们能处理一般的数据库系统了. WinFor

jQuery数组处理详解(含实例演示)_jquery

演示所用数组 var _mozi=['墨家','墨子','墨翟','兼爱非攻','尚同尚贤']; 1. $.each遍历示例[常用] $.each(_mozi,function(key,val){ //回调函数有两个参数,第一个是元素索引,第二个为当前值 alert('_mozi数组中 ,索引 : '+key+' 对应的值为: '+val); }); 2. $.grep()过滤数组[常用] $.grep(_mozi,function(val,key){ //过滤函数有两个参数,第一个为当前元素,

jquery中checkbox使用方法简单实例演示_jquery

和大家分享一段基于jQuery实现checkbox列表全选.反选和不选功能的代码,适用于网页多选后需要进行批量操作的场景(如批量删除等).文章结合实例,代码简洁,基本覆盖选项选择操作的方方面面,希望可以帮到有需要的前端开发爱好者. 引入jquery库<script src="ajax/libs/jquery/1.10.2/jquery.min.js"></script>构建HTML 一般从数据库读出来的列表都需要批量选中以便删除与编辑等,下面我们就来模拟下,实现

Oracle RAC环境下的阻塞(blocking blocked)介绍和实例演示_oracle

RAC环境下的阻塞不同于单实例情形,因为我们需要考虑到位于不同实例的session.也就是说之前查询的v$session,v$lock相应的应变化为全局范围来查找.本文提供了2个查询脚本,并给出实例演示那些session为阻塞者,哪些为被阻塞者.有关阻塞的概念以及单实例环境下的阻塞请参考:Oracle 阻塞(blocking blocked) 1.演示环境 scott@DEVDB> select * from v$version where rownum<2; BANNER ---------