線程實現計時器,多線程間通信


Timer類:計時器

	public class Timer_Test {
	    public static void main(String[] args) {
	        new Timer().schedule(new Test(),new Date(),2000);
	        while(true){
	            System.out.println(new Date());
	            try {
	                Thread.sleep(1000);
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    static class Test extends TimerTask{
	        @Override
	        public void run() {
	            System.out.println("時間到了");
	        }
	    }
	}

  • schedule(TimerTask task, Date firstTime, long period)
    從指定 的時間開始 ,對指定的任務執行重復的 固定延遲執行 。

三線程間通訊

  • 在同步代碼塊中,用哪個對象鎖,就用哪個對象調用wait方法。

    創建在Main方法中創建三個線程

代碼

	public class Demoe {
	    public static void main(String[] args) {
	        Print p = new Print();
	        new Thread() {
	            @Override
	            public void run() {
	                try {
	                    while(true){
	                        p.print1();
	                    }
	
	                } catch (InterruptedException e) {
	                    e.printStackTrace();
	                }
	            }
	        }.start();
	        new Thread() {
	            @Override
	            public void run() {
	                try {
	                    while(true){
	                        p.print2();
	                    }
	
	                } catch (InterruptedException e) {
	                    e.printStackTrace();
	                }
	            }
	        }.start();
	        new Thread() {
	            @Override
	            public void run() {
	                try {
	                    while(true){
	                        p.print3();
	                    }
	
	                } catch (InterruptedException e) {
	                    e.printStackTrace();
	                }
	            }
	        }.start();
	    }

	    static class Print {				//創建內部類並創建三個成員方法,使用WAIT和NOTIFYALL實現線程等待和喚醒
	        static int flag = 1;
	
	        public void print1() throws InterruptedException {
	            synchronized (this) {
	                while (flag != 1) {    //使用wait保證判斷語句能夠執行,如果使用if將會直接喚醒線程而跳過判斷階段。
	                    this.wait();
	                }
	                System.out.print("a");
	                System.out.print("b");
	                System.out.println();
	                flag = 2;
	                this.notifyAll();
	            }
	        }
	
	        public void print2() throws InterruptedException {
	            synchronized (this) {
	                while (flag != 2) {
	                    this.wait();
	                }
	                System.out.print("1");
	                System.out.print("2");
	                System.out.println();
	                flag = 3;
	                this.notifyAll();
	            }
	        }
	
	        public void print3() throws InterruptedException {
	            synchronized (this) {
	                while (flag != 3) {
	                    this.wait();
	                }
	                System.out.print("A");
	                System.out.println("B");
	                flag = 1;
	                this.notifyAll();
	            }
	        }
	
	    }
	
	}
  • 多個線程通信的問題
    • notify()方法是隨機喚醒一個線程
    • notifyAll()方法是喚醒所有線程
    • JDK5之前無法喚醒指定的一個線程
    • 如果多個線程之間通信, 需要使用notifyAll()通知所有線程, 用while來反復判斷條件
  • sleep方法與wait方法區別
    • sleep方法有參數,時間結束后,自動醒來
      wait可以有參數也可以沒有參數,傳入就是在參數時間結束時間后等待,不傳入直接等待
    • sleep方法在同步函數或同步代碼塊中,不釋放鎖
      wait方法在同步函數或者同步代碼塊中釋放鎖

ReentrantLock實現上述功能

  • 可使用if作為判斷語句

  • newCondition()
    返回Condition用於這種用途實例Lock實例。

      ReentrantLock r=new ReentrantLock();
      Condition c=r.newCondition();
    
  • 使用Lock實例開啟鎖

      r.lock
      if( flag!=1){
      	c.await();
      }
    
  • 使用指定其他鎖開啟signal

      c.signal();   
    
  • 關閉Lock;

  •   r.unlock();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM