线程安全,
synchronized的使用,保证方法或代码块操作的原子性、可见性和有序性
参考这篇文章:
7张图带你轻松理解Java 线程安全
public class ThreadDemo { private int x = 0; //这个加了线程锁的方法,下面的runTest()方法内部有两个线程在调用当时,保证了count()的调用只能在 //同一时间被一个线程访问,保证了成员变量x(共享内存里的同一个变量)的原子性,即保证同一时间只能一个线程对x进行调用,并同步到共享内存中。 //如果去掉线程锁(synchronized),则会出现两个输出没有一个值是2000000,这就是因为没线程锁,导致x被同时访问,不能完成写入,又被其他线程调用,同步进去的值就会出错。 private synchronized void count() { x++; } public void runTest() { new Thread() { @Override public void run() { for (int i = 0; i < 1_000_000; i++) { count(); } System.out.println("final x from 1: " + x); } }.start(); new Thread() { @Override public void run() { for (int i = 0; i < 1_000_000; i++) { count(); } System.out.println("final x from 2: " + x); } }.start(); } public static void main(String[] args) { new ThreadDemo().runTest(); } }
个方法主动加锁(Lock)的方式,也能保证成员变量的线程安全,例子如下:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class threaDemo2 { ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); Lock readLock = lock.readLock(); Lock writeLock = lock.writeLock(); private int x = 0; private void count() { writeLock.lock(); try { x++; } finally { writeLock.unlock(); } } private void print(int time) { readLock.lock(); try { for (int i = 0; i < time; i++) { System.out.print(x + " "); } System.out.println(); } finally { readLock.unlock(); } } public void operation(){ new Thread(){ public void run() { for (int i=0;i<1000000;i++) count(); System.out.println("sum1:"+x); } }.start(); new Thread(){ public void run() { for (int i=0;i<1000000;i++) count(); System.out.println("sum2:"+x); } }.start(); } public static void main(String[] args) { new threaDemo2().operation(); } }