wait和sleep的區別 以及 實例演示
參考:
Java多線程中Sleep與Wait的區別 https://uule.iteye.com/blog/1106710
關於多線程的wait與sleep的區別 https://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對象鎖,從頭開始運行,一直到結束。
實例源碼下載:https://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:andro xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android: android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" > <Button android: android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:onClick="OnButton1Click" android:text="Wait" /> <Button android: 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: android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/linearLayout1" android:layout_toLeftOf="@+id/textView1" > <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="@dimen/padding_small" tools:context=".MainActivity" /> </ScrollView> </RelativeLayout>
效果預覽:
最後更新:2017-04-02 16:47:52