還被面試官懟併發編程?來,吃點能量!Java併發編程技術

1、線程池相關

線程超級詳解:blog.csdn.net/cuigx1991/a…html


線程池:www.importnew.com/19011.htmljava

www.jianshu.com/p/098819be0…面試


ExecutorService

blog.csdn.net/yuzhiboyi/a…編程


Callable與Runnable

blog.csdn.net/lu123535884…bash

Callable能夠返回結果,可是runnable不行。併發


上代碼:

public  class TestCallable implements Callable<String>{

    @Override
    public String call() throws Exception {
        Thread.sleep(3000);
        return "Hello World";
    }
}複製代碼
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    TestCallable testCallable = new TestCallable();
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Future<String> future = executorService.submit(testCallable);
    try {
        System.out.println(future.get());
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    System.out.println("11111111111111");
}複製代碼

能夠發現我在TestCallable里加了個sleep,程序仍是會後打印"111111111111"那一個串,說明TestCallable的線程會阻塞主線程,真正緣由是future.get()會阻塞當前線程,直到callable的call方法結束 。異步


CountDownLatchide

能夠阻塞當前線程,等待另一個線程執行完結果後將結果同步返回,異步轉同步。oop

異步轉同步須要注意ui

1)異步的數據必定要是在子線程裏,不然會形成當前線程卡頓。

2)若是須要在主線程裏同步返回數據,可是取數據走的是子線程,子線程不要使用new Handler(Looper.getMainLooper()) 來作延時操做,不然會形成子線程回調沒法countDownLatch減少,最終主線程一直在等待。


在子線程中使用Handler的方法:

HandlerThread handlerThread = new HandlerThread("純24協議對接收到的數據進行分析"){};
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());複製代碼

3)await方法在開其餘線程以後再執行,不然其餘線程尚未開啓起來就把當前線程阻塞了。


2、線程交互

1.喚醒與等待(wait與notify)

相關博客:blog.csdn.net/qq_26504875…

常見異常:http://blog.csdn.net/zhouxiaoyun0228/article/details/7757313

注意事項:1)喚醒與等待是有嚴格的使用條件的,對象監聽器只能在所監聽的線程內調用。

2)wait與notify只能在同步代碼塊裏調用

3)通常一個任務同步方法執行完,調用監聽器wait當前線程。

4)wait與notify雖然是object的方法,可是做用是做爲鎖來控制線程。

5)wait與notify更適用於兩個或多個協同工做的線程


代碼實例:

2個交互的線程類:

public class MyThread1 extends Thread{
    private Object lock;
    private int index = 0;

    public MyThread1(Object lock){
        this.lock = lock;
    }
    @Override
    public void run(){
        synchronized (lock) {
            while (true){
                System.out.println("MyThread1 "+System.currentTimeMillis());
                index++;
                if(index == 10){
                    lock.notify();
                    break;
                }
                if(index % 5 == 0){
                    try {
                        lock.notify();
                        System.out.println("MyThread1 wait");
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }

    }
}複製代碼
public class MyThread2 extends Thread{
    private Object lock;
    private int index = 0;

    public MyThread2(Object lock){
        this.lock = lock;
    }
    @Override
    public void run(){
        synchronized (lock) {
            while (true){
                System.out.println("MyThread2 "+System.currentTimeMillis());
                index++;
                if(index == 10){
                    lock.notify();
                    break;
                }
                if(index % 5 == 0){
                    try {
                        lock.notify();
                        System.out.println("MyThread2 wait");
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}複製代碼


2個交互線程的任務調用類:

public class Thread1Tasker implements ITask{
    private Object lock;
    private final static Thread1Tasker instance = new Thread1Tasker();
    public final static Thread1Tasker getInstance(){
        return instance;
    }

    public Thread1Tasker setLock(Object lock) {
        this.lock = lock;
        return this;
    }

    @Override
    public void start() {
        MyThread1 t1 = new MyThread1(lock);
        t1.start();
    }
}複製代碼


public class Thread2Tasker implements  ITask{
    private Object lock;

    private final static Thread2Tasker instance = new Thread2Tasker();
    public final static Thread2Tasker getInstance(){
        return instance;
    }

    public Thread2Tasker setLock(Object lock) {
        this.lock = lock;
        return this;
    }


    @Override
    public void start() {
        MyThread2 t2 = new MyThread2(lock);
        t2.start();
    }
}複製代碼

main方法裏調用任務:

public class Test3 {
    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        Thread1Tasker.getInstance().setLock(lock)
                .start();
        Thread2Tasker.getInstance().setLock(lock)
                .start();
    }
}複製代碼

結果打印輸出:

MyThread1 1516939281372

MyThread1 1516939281372

MyThread1 1516939281372

MyThread1 1516939281372

MyThread1 1516939281372

MyThread1 wait

MyThread2 1516939281374

MyThread2 1516939281374

MyThread2 1516939281374

MyThread2 1516939281374

MyThread2 1516939281374

MyThread2 wait

MyThread1 1516939281374

MyThread1 1516939281374

MyThread1 1516939281374

MyThread1 1516939281374

MyThread1 1516939281374

MyThread2 1516939281374

MyThread2 1516939281374

MyThread2 1516939281374

MyThread2 1516939281374

MyThread2 1516939281374

能夠發現2個線程任務是交替執行的


3、HandlerThread

www.cnblogs.com/coding-way/…

4、InputStream阻塞

www.cnblogs.com/MyFavorite/…

5、Java併發編程:volatile關鍵字解析

www.cnblogs.com/dolphin0520…

java中volatile關鍵字的含義

www.cnblogs.com/aigongsi/ar…


blog.csdn.net/javazejian/…

最後

喜歡的能夠關注個人公衆號,java小瓜哥的分享平臺。平時整理的技術文和麪試文還有許多資料都放在裏面了

相關文章
相關標籤/搜索