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