JAVA併發編程學習筆記一 ------多線程的建立方式

1.extend Thread 類java

public class extendThreadClass  extends Thread {

    public extendThreadClass(String name){
        /*
        調用父類的構造器,賦值name
         */
        super(name);
    }

    @Override
    public void run() {
        while(!interrupted()){
            System.out.println(getName()+"線程執行了。。。");

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }

    public static void main(String[] args) {
        extendThreadClass demo1 = new extendThreadClass("Thread 1");
        extendThreadClass demo2 = new extendThreadClass("Thread 2");
        demo1.start();
        demo2.start();
        //stop方法只是讓線程無限期等待,並無釋放資源和鎖之類的 interrupt推薦使用  可是使用該方法時,
            須要判斷線程是否處於中斷狀態
        demo1.interrupt();
//        //守護線程,程序執行完,跟着推出,跟隨主線程完畢而完畢
//        demo1.setDaemon(true);



    }
}

須要注意的是複寫父類的run方法,  父類的構造器有多種,原理是多態實現不一樣參數下的構造,
主要參數分爲線程組,線程名稱,runable接口 還有stackSize棧的大小

其次就是setDeamon這個方法,這是個接收boolean值的方法,設置爲true的狀況下,代表爲守護線程,意義在於,主線程執行完成時,不管該線程是否執行完成,也跟着主線程退出而退出,該種方式建立線程無返回值spring

2.implenment Runable多線程

public class implementRunable implements Runnable {
/*
實現runable接口的本質,並非建立一個線程,而是建立一個線程任務,通俗意思就是,我知道我能作什麼,可是我沒有動力本身去作
面向接口
沒有返回值,也不能拋出異常
 */
    @Override
    public void run() {
        while(true){
            System.out.println("thread is run...");
        }
    }

    public static void main(String[] args) {
        //使用Tread類的構造有參構造方法
        Thread thread1 = new Thread(new implementRunable(),"thread1");
        thread1.start();

    }
}

3.使用匿名內部類建立線程併發

/**
 * Created by 14029 on 2018/1/18.
 * 使用匿名內部類建立線程
 * 適用於只使用一次的線程
 * 匿名內部類必須實現一個接口
 * 方法體中本質是實現接口的方法
 *
 * 若是同時實現runable  和複寫run方法  被執行的是被重寫的run方法  ,,,由於不會去調父類的RUN方法 動態分派調用 多態實現
 * 沒有返回值,也不能拋出異常
 */
public class useInnerClasswithoutname {
    public static void main(String[] args) {
//        new Thread(){
//            public void run(){
//                System.out.println("thread is run .....");
//            };
//        }.start();
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("runable is start");
//            }
//        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("runable is start");
            }
        }){
            public void run(){
                System.out.println("Thread is start");
            }
        }.start();
    }
}

4 . implements Callable<V>框架

/**
 * Created by 14029 on 2018/1/18.
 * 泛型指定返回值類型
 */
public class implementsCallable implements Callable <Integer>{
    @Override
    /*
    相似RUN方法
     */
    public Integer call() throws Exception {
        System.out.println("is runing ");
        Thread.sleep(3000);
        return  1;

    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        implementsCallable demo = new implementsCallable();
        //FutureTask提早任務,本質是對runable接口的封裝 實現線程任務
        //提早任務,出現先執行了do other2 --》is runinng  --》do other1 -->result 主線程繼續執行
        FutureTask<Integer> task1 = new FutureTask<Integer>(demo);
        Thread thread = new Thread(task1);
        thread.start();
        System.out.println("i do other2");
        int result = task1.get();
        System.out.println("i do other1");
        System.out.println("Thread result is ..."+result);

    }
}

本質是對runable的繼承和封裝,而後建立task,建立線程,執行taskdom

5.使用線程池建立線程異步

/**
 * Created by 14029 on 2018/1/18.
 * 方便演示用的Executor
 * 同時說明如今的狀況最好不用該種方式
 */
public class usethreadpool {
    public static void main(String[] args) {
        //建立固定大小線程池
        /*
        線程池不容許使用Executors去建立,而是經過ThreadPoolExecutor的方式,這樣的處理方式讓寫的同窗更加明確線程池的運行規則,規避資源耗盡的風險。 說明:Executors各個方法的弊端:
1)newFixedThreadPool和newSingleThreadExecutor:
  主要問題是堆積的請求處理隊列可能會耗費很是大的內存,甚至OOM。
2)newCachedThreadPool和newScheduledThreadPool:
  主要問題是線程數最大數是Integer.MAX_VALUE,可能會建立數量很是多的線程,甚至OOM。
         */
//改方法建立固定大小的線程池
        Executor ThreadPool = Executors.newFixedThreadPool(10);
//該方法隨着線程任務的執行,動態分配線程池的大小
        Executor ThreadPool1 = Executors.newCachedThreadPool();

        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("is running ");
            }
        });

    }

}

6.Use Timermaven

/**
 * Created by 14029 on 2018/1/18.
 *
 * 多用於定時任務,著名框架(quartz)
 * 使用定時器實現多線程
 * 多線程並行處理定時任務時,Timer運行多個TimeTask時,只要其中之一沒有捕獲拋出的異常,
其它任務便會自動終止運行,使用ScheduledExecutorService則沒有這個問題。
 * 有返回值
 * 不可控
 */
public class useTimer {
    /*
    定時任務 0延遲 1000毫秒一次
該方法是鏈式調用,只要其中之一沒有捕獲拋出的異常,
其它任務便會自動終止運行

     */
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //實現定時任務
                System.out.println("task is run....");
            }
        },0,1000);
    }




}

7使用Spring 實現多線程ide

public class useSpring {
    /**使用spring 實現多線程,使用maven 導入Spring依賴
     * 配置註解  @Configuration
     * 第一步配置掃描包 註解:  @ComponentScan("包名")
     * 第二部打開異步   註解: @EnableAsync
     *第三步 建立 異步處理邏輯類   使用@service 將類交給Spring 管理 見 useSpringdomain
     * 第四部 domain
     */
}


/*
config類
Config.java
@Configuration
@ComponentScan("包名")
@EnableAsync
public class config{}
 */

/*
useSpringdomain.java
@Service
public class useSpringdomain{
@Async  異步
public void a(){
while(true){
//todo
}
@Async  異步
public void b(){
while(true){
//todo
}
}
}
 */

/*
domain.java
核心:
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(config.class)
useSpringdomain demo1 =ac.getBean(useSpringdomain.class)
demo1.a();


 */

8 使用Lambda實現多線程線程

parallelStream 經過併發流的方式實現多線程。。。沒有具體研究

相關文章
相關標籤/搜索