多執行緒Day02

东方语虑發表於2024-10-01

靜態代理

package com.dongfangyulv.demo01;

//靜態代理模式總結:
//真實物件和代理物件都要實現同一個介面
//代理物件要代理真實角色

//好處:
//代理物件可以做很多真實物件做不了的事情
//真實物件專注做自己的事情

public class StacticProxy {
    public static void main(String[] args) {

        You you = new You();//你要結婚

        WeddingCompany weddingCompany = new WeddingCompany(new You());
        weddingCompany.Marry();
    }
}

interface Marry{

    void Marry();
}

//真實角色
class You implements Marry{
    @Override
    public void Marry() {
        System.out.println("新婚快樂");
    }
}

//代理角色
class WeddingCompany implements Marry{

    //代理真實目標角色
    private Marry target;

    public WeddingCompany(Marry target) {
        this.target = target;
    }

    @Override
    public void Marry() {
        before();
        this.target.Marry();//這就是真實物件
        after();
    }

    private void before() {
        System.out.println("結婚前");
    }

    private void after() {
        System.out.println("結婚後");
    }
}

Lamda表示式

  • 避免匿名內部類過多

  • 實質屬於函數語言程式設計的概念

    • 函式式介面:任何介面如果只包含一個抽象方法,那麼他就是一個函式式介面

      public interface Runnable{
          public abstract void run();
      }
      
  • 去掉了一堆沒有意義的程式碼,只留下核心的邏輯

package com.dongfangyulv.lambda;
/*
推導lamda表示式
*/
public class TestLambda1 {

    //3.靜態內部類
    static class Like2 implements ILike{
        @Override
        public void lambda() {
            System.out.println("I like lambda2");
        }
    }

    public static void main(String[] args) {
        ILike like = new Like();
        like.lambda();

        like = new Like2();
        like.lambda();

        //4.區域性內部類
        class Like3 implements ILike{
            @Override
            public void lambda() {
                System.out.println("I like lambda3");
            }
        }
        like = new Like3();
        like.lambda();

        //5.匿名內部類,沒有類的名稱,必須藉助介面或者父類
        like = new ILike(){
            @Override
            public void lambda() {
                System.out.println("I like lambda4");
            }
        };
        like.lambda();

        //6.用lambda簡化
        like = () -> {
            System.out.println("I like lambda5");
        };
        like.lambda();
    }
}

//1.定義一個函式式介面
interface ILike{
    void lambda();
}

//2.實現類
class Like implements ILike{
    @Override
    public void lambda() {
        System.out.println("I like lambda1");
    }
}
package com.dongfangyulv.lambda;

public class TestLambda2 {

    public static void main(String[] args) {
        ILove love = null;

        //Lambda表示簡化
        love = (int a) ->{
            System.out.println("I love you" + a);
        };

        //簡化1.引數型別
        love = (a) ->{
            System.out.println("I love you" + a);
        };

        //簡化2.簡化括號
        love = a ->{
            System.out.println("I love you" + a);
        };

        //簡化3.去花括號
        love = a -> System.out.println("I love you" + a);

        //總結:
        //Lambda表示式只能有一行程式碼的情況下才能簡化,如果有多行程式碼,就用程式碼塊包裹
        //前提是介面為函式式介面
        //多個引數也可以去掉引數型別,要去就都去了,必須加上括號

        love.love(520);
    }
}

interface ILove{
    void love(int a);
}

執行緒狀態

  • new

    尚未啟動的執行緒

  • runnable

    在Java虛擬機器中執行的執行緒

  • blocked

    被阻塞等待監視器鎖定的執行緒

  • waiting

    正在等待另一個執行緒執行特定動作的執行緒

  • timed_waiting

    正在等待另一個執行緒執行動作達到指定等待時間的執行緒

  • terminated

    已退出的執行緒

執行緒停止

  • 不推薦使用JDK提供的stop( )、destory( )方法
  • 推薦執行緒自己停止下來
  • 建議使用一個標誌位進行終止變數,當flag = false,則終止執行緒執行
package com.dongfangyulv.state;

//測試stop
//1.建議執行緒正常停止--->利用次數,不建議死迴圈
//2.建議使用標誌位--->設定一個標誌位
//3.不要使用stop或者destroy等過時或者JDK不建議使用的方法
public class TestStop implements Runnable{
    //1.設定一個標誌位
    private boolean flag = true;

    @Override
    public void run() {
        int i = 0;
        while (flag){
            System.out.println("run...Thread" + i++);
        }
    }

    //2.設定一個公開的方法停止執行緒,轉換標誌位
    public void stop(){
        this.flag = false;
    }

    public static void main(String[] args) {
        TestStop testStop = new TestStop();

        new Thread(testStop).start();

        for (int i = 0; i < 100; i++) {
            System.out.println("main" + i);
            if (i == 90){
                //呼叫stop方法,切換標誌位,讓執行緒停止
                testStop.stop();
                System.out.println("執行緒停止了");
            }
        }
    }
}

執行緒休眠

  • sleep(時間)指定當前執行緒阻塞的毫秒數
  • sleep存在異常InterruptedException
  • sleep時間達到後執行緒進入就緒狀態
  • sleep可以模擬網路延時,倒數計時等
  • 每一個物件都有一個鎖,sleep不會釋放鎖
package com.dongfangyulv.state;

import java.text.SimpleDateFormat;
import java.util.Date;

//模擬網路延時:放大問題的發生性
public class TestSleep {
    public static void main(String[] args) {
        //列印當前系統時間
        Date startTime = new Date(System.currentTimeMillis());

        while (true) {
            try {
                Thread.sleep(1000);
                System.out.println(new SimpleDateFormat("hh:mm:ss").format(startTime));
                startTime = new Date(System.currentTimeMillis());//更新當前時間
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

//        模擬倒數計時
//        try {
//            tenDown();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
    }

    //模擬倒數計時
    public static void tenDown() throws InterruptedException{
        int num = 10;

        while (true) {
            Thread.sleep(1000);
            System.out.println(num--);
            if (num == 0) {
                break;
            }
        }
    }
}

執行緒禮讓

  • 禮讓執行緒,讓當前正在執行的執行緒暫停,但不阻塞
  • 將執行緒從執行狀態轉為就緒狀態
  • 讓CPU重新排程,禮讓不一定成功,看CPU心情
package com.dongfangyulv.state;

//測試禮讓執行緒
//禮讓不一定成功,看CPU心情
public class TestYield {
    public static void main(String[] args) {
        MyYield myYield = new MyYield();

        new Thread(myYield,"a").start();
        new Thread(myYield,"b").start();
    }
}

class MyYield implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "執行緒開始執行");
        Thread.yield();//執行緒禮讓
        System.out.println(Thread.currentThread().getName() + "執行緒停止執行");
    }
}

執行緒強制執行

  • Join合併執行緒,待此執行緒執行完成後,再執行其他執行緒,其他執行緒阻塞
package com.dongfangyulv.state;

//測試Join方法
//插隊
public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("VIP" + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start();

        //主執行緒
        for (int i = 0; i < 500; i++) {
            if (i == 200) {
                thread.join();
            }
            System.out.println("main" + i);
        }
    }
}

執行緒狀態觀測

package com.dongfangyulv.state;

//觀察測試執行緒的狀態
public class TestState {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("=========================================================");
        });

        //觀察狀態
        Thread.State state = thread.getState();
        System.out.println(state);//NEW

        //觀察啟動後
        thread.start();//啟動執行緒
        state = thread.getState();
        System.out.println(state);//RUN

        while (state != Thread.State.TERMINATED) {//只要執行緒不終止,就一直輸出狀態
            Thread.sleep(100);
            state = thread.getState();//更新執行緒狀態
            System.out.println(state);//輸出狀態
        }
    }
}

相關文章