volatile
volatile保证了多线程之间的可见性。用volatile修饰的变量,在多个线程中都可以读到最新的值,但是不保证变量的原子性。
那么volatile如何保证多线程之间的可见性呢?
首先,需要说明下线程安全问题引起的原因。每个线程在计算的时候会读取主内存中的数据到本地变量表中,计算后再将数据写回到主内存中。假设,每个线程读取到的主内存中的数据的值是一致的,在各自线程内存中计算后,会得到不同的结果,这个时候再讲结果会写到主内存中,那么先写回主内存中的线程的计算过程就被覆盖掉了。这样就造成了线程安全问题。
被volatile修饰的变量,对于虚拟机来说就是被共享的变量,所以不会在该变量上进行指令的重排序,也不会在线程内存中缓存该变量,直接在主内存中存取,所以保证了每个线程读取到的数据都是最新的。
synchronized
synchronized关键字可以修饰代码块、方法、静态方法以及类。用sysnchronized时要注意锁定的是对象还是类,如果锁定的是类,相当于锁定了该类的所有对象。
synchronized修饰的方法或者代码块,使该方法和代码块对多线程互斥,只有一个线程可以进入该方法或者代码块(方法或者代码块以下统称为方法,便于说明)。多个线程访问synchronized修饰的方法时,会尝试获取对象的mointor锁,当获取到mointor时可以进入该同步方法进行运算,没有获取到mointor锁的线程会存在虚拟机的一个synchronized的队列中,当mointor被释放的时候,从synchronized队列中出一个线程获取mointor锁