我們上面講了wait的用法,下面我們來講seleep的用法。首先我們還是將上一篇的上體育課的例子拿來做一個示例
我們在里面用一下sleep方法
package ThreadTest; import java.text.SimpleDateFormat; import java.util.Date; /** * Thread sleep運用實例 * @author lingfengz * */ public class SleepTest { public static void main(String[] args) { new Thread(new Sleep1()).start(); new Thread(new Sleep2()).start(); } public static class Sleep1 implements Runnable{ /** * 實現體育老師安排體育課代表進行點名 */ @Override public void run() { // TODO Auto-generated method stub //這個步驟我們可以想象成鎖住的是一節體育課 synchronized (SleepTest.class) { System.out.println("體育老師安排體育委員進行點名"); try { //體育老師開始看手表,准備上課 System.out.println("體育老師開始等待時間:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date())); //體育老師在樓下等待,然后玩一會手機,休息1000L時間 Thread.sleep(1000L); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("體育老師結束等待時間:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date())); //System.out.println("體育老師得到點名的結果開始上課"); System.out.println("體育老師去操場開始上課"); } } } public static class Sleep2 implements Runnable{ /** * 實現體育課代表進行隊列點名 */ @Override public void run() { // TODO Auto-generated method stub synchronized (SleepTest.class) { System.out.println("體育委員進行點名"); try { //點名需要花費的時間 Thread.sleep(1000L); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("體育委員點名結束"); //通知體育老師點名結束了 //WaitTest.class.notify(); System.out.println("體育課代表帶人去操場"); } } } } 運行結果: 體育老師安排體育委員進行點名 體育老師開始等待時間:2019/03/18-13:44:53:674 體育老師結束等待時間:2019/03/18-13:44:54:676 體育老師去操場開始上課 體育委員進行點名 體育委員點名結束 體育課代表帶人去操場
從上面可以看出sleep並不會釋放鎖。那么如果sleep的時間過長會怎么樣?
package ThreadTest; import java.text.SimpleDateFormat; import java.util.Date; /** * Thread sleep運用實例 * @author lingfengz * */ public class SleepTest { public static void main(String[] args) { new Thread(new Sleep1()).start(); new Thread(new Sleep2()).start(); } public static class Sleep1 implements Runnable{ /** * 實現體育老師安排體育課代表進行點名 */ @Override public void run() { // TODO Auto-generated method stub //這個步驟我們可以想象成鎖住的是一節體育課 synchronized (SleepTest.class) { System.out.println("體育老師安排體育委員進行點名"); try { //體育老師開始看手表,准備上課 System.out.println("體育老師開始等待時間:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date())); //體育老師在樓下等待,然后玩一會手機,休息1000L時間 Thread.sleep(10000L); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("體育老師結束等待時間:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date())); //System.out.println("體育老師得到點名的結果開始上課"); System.out.println("體育老師去操場開始上課"); } } } public static class Sleep2 implements Runnable{ /** * 實現體育課代表進行隊列點名 */ @Override public void run() { // TODO Auto-generated method stub synchronized (SleepTest.class) { System.out.println("體育課老師已經到樓下了"); System.out.println("體育委員開始點名時間:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date())); System.out.println("體育委員進行點名"); try { //點名需要花費的時間 Thread.sleep(1000L); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("體育委員點名結束"); //通知體育老師點名結束了 //WaitTest.class.notify(); System.out.println("體育課代表帶人去操場"); } } } } 運行結果: 體育老師安排體育委員進行點名 體育老師開始等待時間:2019/03/18-13:49:47:031 體育老師結束等待時間:2019/03/18-13:49:57:046 體育老師去操場開始上課 體育課老師已經到樓下了 體育委員開始點名時間:2019/03/18-13:49:57:046 體育委員進行點名 體育委員點名結束 體育課代表帶人去操場
這么看來sleep睡的時間太長會導致,線程長期持有鎖。那么有沒有方法可以提前喚醒他呢?方法是有的
我們來看看interrupt怎么來提前喚醒
package ThreadTest; import java.text.SimpleDateFormat; import java.util.Date; /** * Thread sleep運用實例 * @author lingfengz * */ public class SleepTest { public static void main(String[] args) { Date date = new Date(); Thread thread1 = new Thread(new Sleep1(date)); thread1.start(); //學校規定最多准備5分鍾就得上課 while(true){ //如果現在的時間超過5分鍾,老師必須去上課 if(new Date().getTime()>new Date((date.getTime()+2*1000*3)).getTime()){ thread1.interrupt(); break; } } Thread thread2 = new Thread(new Sleep2(date)); thread2.start(); } public static class Sleep1 implements Runnable{ private Date date; private int oneMin = 2*1000; public Sleep1(Date date){ this.date = date; } /** * 實現體育老師安排體育課代表進行點名 */ @Override public void run() { // TODO Auto-generated method stub //這個步驟我們可以想象成鎖住的是一節體育課 synchronized (SleepTest.class) { System.out.println("體育老師安排體育委員進行點名"); try { //體育老師開始看手表,准備上課 System.out.println("體育老師開始等待時間:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(date)); //體育老師在樓下等待,然后玩一會手機,休息10分鍾時間 Thread.sleep(oneMin*6); } catch (InterruptedException e) { //老師被警告,要去上課了 System.out.println("老師被警告了,過了五分鍾了。必須要去上課了"); } System.out.println("體育老師結束等待時間:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date())); //System.out.println("體育老師得到點名的結果開始上課"); System.out.println("體育老師去操場開始上課"); } } } public static class Sleep2 implements Runnable{ private Date date; private int oneMin = 60*1000; public Sleep2(Date date){ this.date = date; } /** * 實現體育課代表進行隊列點名 */ @Override public void run() { // TODO Auto-generated method stub synchronized (SleepTest.class) { System.out.println("體育課老師已經到樓下了"); System.out.println("體育委員開始點名時間:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date())); System.out.println("體育委員進行點名"); try { //點名需要花費的時間 Thread.sleep(1000L); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("體育委員點名結束"); //通知體育老師點名結束了 //WaitTest.class.notify(); System.out.println("體育課代表帶人去操場"); } } } } 運行結果: 體育老師安排體育委員進行點名 體育老師開始等待時間:2019/03/18-14:35:21:637 老師被警告了,過了五分鍾了。必須要去上課了 體育老師結束等待時間:2019/03/18-14:35:27:638 體育老師去操場開始上課 體育課老師已經到樓下了 體育委員開始點名時間:2019/03/18-14:35:27:639 體育委員進行點名 體育委員點名結束 體育課代表帶人去操場
從這里我們可以看出 sleep時間過長的話,我們可以通過interrupt方法來進行狀態的修改。但是必須要catch捕捉到。然后再進行下一步的操作
我們來總結一下sleep的作用:首先並不會釋放鎖。但是會釋放cpu的資源,如果sleep時間過長可以調用interrupt方法進行喚醒。但是要捕捉異常。會進入異常。