1.使用valatile关键字
使用volatile关键字的作用:
1- 当其他线程对变量做改变时,能够及时的反映到当前线程中
2- 确保当前线程对变量的修改,能够及时的写回共享主内存中,并被其他线程所见
3- 使用volatile声明的变量,编译器会确保其有序性
2.使用同步关键字synchronized
synchronized使用情况:
1- 使用在方法中
public synchronized void method() {}
当method方法被调用时,需要获取当前对象的锁,如果当前对象的锁被其他线程持有,则调用线程会等待,当其他线程调用结束后,锁会释放,当前线程获取到锁后才能执行。
2- 使用在代码块中
synchronized (this) {
System.out.println("bbbbbbbbb");
}
当一个方法内部不需要同步的代码执行时间比较长的时候可以使用代码块同步的方式
3- synchronized用于static
public synchronized static void method3() {
}
当synchronized用于static方法时,相当去将锁加在了class对象之上,所有调用方法时需要获得class对象的锁,儿class对象只有一份。
3.使用wait、notify、notifyAll
4.ReentrantLock重入锁
ReentrantLock在jdk6以前的版本中性能较synchronized高,在6及其后的版本中基本相同,不做介绍
5.ReadWriteLock读写锁
读写锁在多线程读的时候可以并行,因此效率较串行的锁效率高。
public class ReadWriteLockTest {
private static Lock lock = new ReentrantLock();
private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static ReadLock readLock = readWriteLock.readLock();
private static WriteLock writeLock = readWriteLock.writeLock();
private static Integer value;
public Object handleRead() throws InterruptedException {
try {
lock.lock();
Thread.sleep(10);
return value;
} finally {
lock.unlock();
}
}
public void handleWrite(int index) throws InterruptedException {
try {
lock.lock();
Thread.sleep(10);
value = index;
} finally {
lock.unlock();
}
}
public Object handleRead2() throws InterruptedException {
try {
readLock.lock();
Thread.sleep(10);
return value;
} finally {
lock.unlock();
}
}
public void handleWrite2(int index) throws InterruptedException {
try {
writeLock.lock();
Thread.sleep(10);
value = index;
} finally {
lock.unlock();
}
}
}
6.Condition对象
暂不介绍
7.ThreadLock线程局部变量
ThreadLock也是一种并发线程访问变量的控制方法,但是与同步有本质的不同,ThreadLocal不提供锁,而是使用的空间换时间的方法,为每一个线程提供变量的副本,以保证线程的安全。