线程安全,
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();
}
}