1. String.format进行格式化
String.format(Locale.CHINA,"http://%s:%d","192.168.0.1",55)
2. 字节转为hex字符串
private static String bytesToHexString(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (byte b : bytes) {
sb.append(String.format("%03o", b)+" ");
//%02x 意思是以16进制2位输出,不足以0补齐,x是指16进制
//二进制是B,十进制是D,八进制O,十六进制是x
}
return sb.toString();
}
3. InetAddress
InetAddress类是Java包装用来表示IP地址的高级表示。几乎所有的Java网络相关的类都和它有关系。可以通过它来获取本机的ip地址,还可以通过主机名来查找ip地址。
InetAddress.getLocalHost().getAddress();//获取本机的地址
InetAddress.getByName("host");//根据主机名获取
InetAddress.getByName("127.0.0.1");//获取本机的代理地址
1、127.0.0.1是回送地址,指本地机,一般用来测试使用。回送地址是本机回送地址(Loopback Address),即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程间通信,无论什么程序,一旦使用回送地址发送数据,协议软件立即返回,不进行任何网络传输。
2、localhost是本地DNS解析的127.0.0.1的域名,这个你打开本机的hosts文件就可以看到,一般位于c:\windows\system32\driver\etc下,一般在最后有这么一行:
4. CountDownLatch
CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信。
用法:
1:某一线程在开始运行前等待n个线程执行完毕。将CountDownLatch的计数器初始化为n new CountDownLatch(n) ,每当一个任务线程执行完毕,就将计数器减1 countdownlatch.countDown(),当计数器的值变为0时,在CountDownLatch上 await() 的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。
2:实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的CountDownLatch(1),将其计数器初始化为1,多个线程在开始执行任务前首先 coundownlatch.await(),当主线程调用 countDown() 时,计数器变为0,多个线程同时被唤醒。
public static void main(String[] str) {
CountDownLatch countDownLatch = new CountDownLatch(1);
try {
new Thread(new CountDownLatchTestRunnable(countDownLatch)).start();
Logger.l("wait,"+ TimeUtil.getCurrentDateString());
countDownLatch.await();//调用了await后,将等待在这里,在CountDownLatch调用countDown();
//后进行计数,直到计数到0,才会唤醒,执行下面的操作
Logger.l("awake 可以执行下面的操作了,"+ TimeUtil.getCurrentDateString());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class CountDownLatchTestRunnable implements Runnable{
CountDownLatch countDownLatch;
public CountDownLatchTestRunnable(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
Thread.sleep(3000);
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
wait,20181022 11:35:40
awake 可以执行下面的操作了,20181022 11:35:43
5. AtomicInteger
在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。
6. CopyOnWriteArrayList
写入时复制(CopyOnWrite,简称COW)思想是计算机程序设计领域中的一种优化策略。其核心思想是,如果有多个调用者(Callers)同时要求相同的资源(如内存或者是磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者视图修改资源内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。
原理很简单:首先是获得了当前数组的一个拷贝获得一个新的数组,然后在这个新的数组上完成我们想要的操作。当操作完成之后,再把原有数组的引用指向新的数组。
CopyOnWrite只能保证数据最终的一致性,不能保证数据的实时一致性。
所以对于CopyOnWrite容器来说,只适合在读操作远远多于写操作的场景下使用,比如说缓存。所以CopyOnWriteArrayList是线程安全的
7. 线程里可以通过同步锁锁定进行等待
private final Object wc = new Object();
private void waitForSourceData() {
synchronized (wc) {
try {
wc.wait(1000);
} catch (InterruptedException e) {
}
}
}
8. threadlocal与线程的普通成员变量的区别
threadlocal类型的变量时每个线程独有的,而普通的成员变量是线程共享的