小隨筆

1 怎麼知道一個端口號有沒有被佔用,被哪一個進程佔用。html

(1)windows下:(以3306爲例)mysql

netstat -ano | findstr 3306linux

 

LISTENING表示被佔用,4552表示佔用進程號,接下來查進程號。nginx

tasklist | finder 4552sql

很容易知道3306被mysql的mysqld進程佔用了。windows

(2)linux下:(以8082爲例)服務器

netstat -anp | grep 8082session

LISTEN表示端口被佔用,很明顯被nginx的進程佔用,進程號131763,能夠經過ps命令查看詳情:ps aux | grep 131763ide

 

2 簡單理解CountDownLatch和CyclicBarrier的做用this

(1)好比有一個線程A,它要等待其餘4個線程執行完畢以後才能執行,此時就能夠利用CountDownLatch來實現這種功能了。

簡單使用方法:構造對象的時候設置count 值(此例count=4),在A線程裏await一下將當前線程掛起,其餘4個線程完成特定功能後手動調用countDown方法,4次countDown後A線程繼續執行後面任務。

經典示例:在主線程中zookeeper構造會話以後,調用await(防止會話未建立就執行增刪該查的操做),服務器建立會話成功後回調Watcher的process方法,在該方法裏countDown。此時能夠主線程後續繼續操做。詳細看代碼:

public class ZKTest implements Watcher {

    private static CountDownLatch connectedSemaphore = new CountDownLatch(1);

    public static void main(String[] args) throws Exception {

        ZooKeeper zooKeeper = new ZooKeeper("127.0.0.1:2181", 5000, new ZKTest());
        System.out.println(zooKeeper.getState());
        connectedSemaphore.await();
        zooKeeper.create("/zk-test", "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
        System.out.println("zooKeeper session established");

    }

    @Override
    public void process(WatchedEvent watchedEvent) {
        System.out.println("receive WatchedEvent: " + watchedEvent);
        if (Event.KeeperState.SyncConnected == watchedEvent.getState()) {
            connectedSemaphore.countDown();
        }
    }
}

 感受CountDownLatch和join很像啊,可是CountDownLatch更靈活,join必要要等到線程結束後才能處理後續代碼,而CountDownLatch是須要count減到0就好了。不清楚的能夠看博客瞭解細節https://www.jianshu.com/p/795151ac271b

 

(2)倘若有若干個線程都要進行操做A,而且只有全部線程都完成操做A以後,這些線程才能繼續作後面的事情,此時就能夠用CyclicBarrier。示例代碼以下:

public class CyclicBarrierTest {

    public static void main(String[] args) {
        int parties = 3;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(parties);
        for (int i = 0; i < parties; i++) {
            MyTask myTask = new MyTask(cyclicBarrier);
            new Thread(myTask).start();
        }
    }
}

class MyTask implements Runnable {

    private CyclicBarrier cyclicBarrier;

    public MyTask(CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + ":start A operation");
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() + ":end A operation");
            cyclicBarrier.await();
            System.out.println(Thread.currentThread().getName() + ":another operation");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

輸出

Thread-0:start A operation
Thread-2:start A operation
Thread-1:start A operation
Thread-1:end A operation
Thread-2:end A operation
Thread-0:end A operation
Thread-2:another operation
Thread-0:another operation
Thread-1:another operation

 關於這兩個更多細節請移步博客:http://www.javashuo.com/article/p-simfkhnj-b.html

相關文章
相關標籤/搜索