ThreadLocal

为每个使用变量的线程提供独立的变量副本,这样每个线程就可以独立改变自己的副本,不会影响其他的线程;

InheritableThreadLocal在原有基础上进行了扩展,包括其子线程在内的线程都可以实现数据的同步;

synchronized

synchronized修饰的代码块或是方法都可以看作是一个原子操作;

一个线程执行互斥代码的过程:

1.获得同步锁;

2.清空工作内存;

3.从主内存拷贝对象到工作内存;

4.执行代码;

5.更新主内存内容;

6.释放同步锁;

volatile

volatile修饰的成员变量在每次被线程访问时,都会强制从共享内存中重新读该成员变量。同时,当成员变量发生变化时,会强制线程将变化后的结果写入共享内存总中。

但是volatile只提供了线程可见性,并没有提供线程的互斥性,故不能保证线程安全性和原子性;

volatile相当于synchronized的弱实现,但是效率比前者高。

由于其上述特性,volatile多应用于以下场合:状态标志、一次性安全发布、独立观察。


sleep、wait、notify

sleep会暂停一个进程,但是不会释放锁,等sleep时间到了会继续进行。

wait也会暂停一个进程,但是会释放锁,等时间到了需要通过notify或是allnotify执行。

可以看下面的例子:


public static void main(String[] args) throws Exception {
        final Object lock="";
        Thread t1=new Thread(){
            public void run(){
                try {
                    log.info("t1 wait begin");//1
                    synchronized (lock) {
                        log.info("t1 get lock, wait begin");//2
                        lock.wait();
                        log.info("t1 wait end,release lock");//9
                        lock.notifyAll();
                    }
                    log.info("t1  wait end");//10
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        t1.start();
        log.info("t1 start and sleep");//3
        for(int i=0;i<10000001;i++){
            if(i==10000000)
                log.info("i end");//4
        }
        Thread.sleep(5000);
        log.info("sleep(5000) end");//5

        log.info("main lock begin");//6
        synchronized (lock) {
            log.info("main get lock");//7
            lock.notify();
            log.info("notify");//8
            Thread.sleep(10000);
            log.info("sleep 10000 end");//11
            log.info("main wait begin ");//12
            lock.wait();
            log.info("main wait end");//13
        }
        log.info("main lock end");
    }