问:什么是java间的线程同步
答:
是什么?:是一种机制,一种在多线程环境下,确保同一时刻,只有一个线程可以执行共享资源的临界区代码 为什么?:因为在多线程环境下,多个线程同时对共享资源进行访问或写入的操作,可能会导致数据不一致、静态条件、死锁等问题的产生 怎么做?:通过加锁的方式,来实现临界区的代码在同一时刻只能被一个线程执行 具体实现:
1.synchronized关键字,通过在方法或者代码块上添加synchronized关键字,实现同步机制 2.通过ReenTrantLock类的lock()和unlock()方法实现 3.通过原子类实现,Java中的Atomic类提供了一系列的原子类,例如:AtomicInteger、AtomicLong、AtomicRefrence等,通过这些原子类,可以实现在不使用java代码加锁的形式实现同步机制,原理是这些原子类通过硬件级别的原子操作来实现操作的原子性。
本题相关知识点(以下内容为笔者在学习本题时不清楚的知识点,上述解答在阅读时,如没有疑问,下述知识点可直接跳过):
共享资源: 在多线程或者分布式系统中,多个线程、进程、组件都可以执行访问或者写入的操作的资源,常见的共享资源是数据或者对象,比如:实例变量、静态变量、集合等 静态条件: 当多个线程竞争同一个资源的时候,线程的输出或者行为,取决于线程被CPU调度的时机,而不是程序本身的逻辑 临界区: 是一段代码,这段代码里写的是,在多线程环境下,对共享资源进行访问或写入的代码逻辑
synchronized实现同步机制:
1.synchronized加在实例方法上,锁住的对象是调用方法的实例对象 2.synchronized加在静态方法上,锁住的是类对象 3.synchronized加在代码块上,可以指定一个特定的对象作为锁,此方法更加灵活 4.
public class Counter {
private int count = 0;
// 同步实例方法
public synchronized void increment() {
count++;
}
// 同步静态方法
public static synchronized void staticIncrement() {
// 静态方法的锁是类的 Class 对象
}
}
public class Counter {
// 创建锁对象
private final Object lock = new Object();
private int count = 0;
public void increment() {
// 加在代码块上,指定特定对象为锁
synchronized (lock) {
count++;
}
}
}
ReenTrantLock实现同步机制:
ReenTrantLock是java的JUC中包下的一个类,提供了lock()方法加锁和unlock方法解锁,相比于synchronized来说更加的灵活,因为它允许手动添加或者释放锁,而syunchronized不允许手动释放,并且它支持公平锁、非公平锁、条件变量等功能。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private final Lock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock(); // 获取锁
try {
count++;
} finally {
lock.unlock(); // 释放锁
}
}
}
原子类实现同步机制实例:
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet(); // 原子操作
}
public int getCount() {
return count.get();
}
}