1.减少锁的持有时间(具体到方法)
2.减小锁的粒度
将大对象,拆成小对象,大大增加并行度,降低锁竞争. 如此一来偏向锁,轻量级锁成功率提高. 使用ReadWriteLock就可以做到读写分离,比如ConcurrentHashMap中使用的锁分离
3. 锁粗化:多个同步块合并,减少对锁的请求和释放
4. 锁消除:锁消除是Java虚拟机在JIT编译时(jdk1.6以后),通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁,通过锁消除,可以节省毫无意义的请求锁时间。
可以通过启动将其优化,将锁消除,前提是java必须运行在server模式(server模式会比client模式作更多的优化),同时必须开启逃逸分析:
-server -XX:+DoEscapeAnalysis -XX:+EliminateLocks
其中+DoEscapeAnalysis表示开启逃逸分析,+EliminateLocks表示锁消除
5.引用ThreadLocal
除了控制有限资源访问外, 我们还可以增加资源来保证对象线程安全.

对于一些线程不安全的对象, 例如SimpleDateFormat, 与其加锁让100个线程来竞争获取,

不如准备100个SimpleDateFormat, 每个线程各自为营, 很快的完成format工作.

public class ThreadLocalDemo {

	public static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal();

	public static void main(String[] args){
		ExecutorService service = Executors.newFixedThreadPool(10);
		for (int i = 0; i < 100; i++) {
			service.submit(new Runnable() {
				@Override
				public void run() {
					if (threadLocal.get() == null) {
						threadLocal.set(new SimpleDateFormat("yyyy-MM-dd"));
					}

					System.out.println(threadLocal.get().format(new Date()));
				}
			});
		}
	}
}

对于set方法, 先获取当前线程对象, 然后getMap()获取线程的ThreadLocalMap, 并将值放入map中.
该map是线程Thread的内部变量, 其key为threadlocal, vaule为我们set进去的值
手动释放: 调用threadlocal.set(null)或者threadlocal.remove()即可
自动释放: 关闭线程池, 线程结束后, 自动释放threadlocalmap.