← 返回首页

Java锁机制详解

📂 java ⏱ 4 min 629 words

什么是锁机制

锁机制是Java并发编程中保证线程安全的核心手段,通过互斥访问共享资源来避免竞态条件。

synchronized关键字

方法锁

public class SynchronizedMethodDemo {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedMethodDemo demo = new SynchronizedMethodDemo();

        Runnable task = () -> {
            for (int i = 0; i < 10000; i++) {
                demo.increment();
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("最终计数: " + demo.getCount());
    }
}

代码块锁

public class SynchronizedBlockDemo {
    private final Object lock = new Object();
    private int balance = 1000;

    public void withdraw(int amount) {
        synchronized (lock) {
            if (balance >= amount) {
                balance -= amount;
                System.out.println("取款成功,余额: " + balance);
            } else {
                System.out.println("余额不足");
            }
        }
    }

    public void deposit(int amount) {
        synchronized (lock) {
            balance += amount;
            System.out.println("存款成功,余额: " + balance);
        }
    }
}

静态方法锁

public class StaticSyncDemo {
    private static int staticCount = 0;

    public static synchronized void staticIncrement() {
        staticCount++;
    }

    public static synchronized int getStaticCount() {
        return staticCount;
    }
}

ReentrantLock

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo {
    private final Lock lock = new ReentrantLock();
    private int balance = 1000;

    public void transfer(int amount) {
        lock.lock();
        try {
            if (balance >= amount) {
                balance -= amount;
                System.out.println(Thread.currentThread().getName() +
                    "转出: " + amount + ", 余额: " + balance);
            }
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantLockDemo demo = new ReentrantLockDemo();

        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                demo.transfer(10);
            }
        };

        Thread t1 = new Thread(task, "线程A");
        Thread t2 = new Thread(task, "线程B");

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("最终余额: " + demo.balance);
    }
}

可中断锁

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class InterruptibleLockDemo {
    private final Lock lock = new ReentrantLock();

    public void doWork() {
        lock.lock();
        try {
            System.out.println("获取锁,开始工作");
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            System.out.println("工作被中断");
        } finally {
            lock.unlock();
            System.out.println("释放锁");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        InterruptibleLockDemo demo = new InterruptibleLockDemo();

        Thread worker = new Thread(demo::doWork);
        worker.start();

        Thread.sleep(1000);
        System.out.println("中断工作线程");
        worker.interrupt();

        worker.join();
    }
}

读写锁

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private int data = 0;

    public int read() {
        rwLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() +
                "读取数据: " + data);
            return data;
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public void write(int value) {
        rwLock.writeLock().lock();
        try {
            data = value;
            System.out.println(Thread.currentThread().getName() +
                "写入数据: " + data);
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReadWriteLockDemo demo = new ReadWriteLockDemo();

        Runnable reader = () -> {
            for (int i = 0; i < 3; i++) {
                demo.read();
            }
        };

        Runnable writer = () -> {
            for (int i = 0; i < 3; i++) {
                demo.write(i * 100);
            }
        };

        Thread[] readers = new Thread[3];
        for (int i = 0; i < 3; i++) {
            readers[i] = new Thread(reader, "读线程" + i);
        }

        Thread writerThread = new Thread(writer, "写线程");

        for (Thread r : readers) {
            r.start();
        }
        writerThread.start();

        for (Thread r : readers) {
            r.join();
        }
        writerThread.join();
    }
}

条件锁

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionLockDemo {
    private final Lock lock = new ReentrantLock();
    private final Condition notEmpty = lock.newCondition();
    private final Condition notFull = lock.newCondition();

    private final int[] buffer = new int[5];
    private int count = 0;

    public void produce(int item) throws InterruptedException {
        lock.lock();
        try {
            while (count == buffer.length) {
                notFull.await();
            }
            buffer[count++] = item;
            System.out.println("生产: " + item);
            notEmpty.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public int consume() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0) {
                notEmpty.await();
            }
            int item = buffer[--count];
            System.out.println("消费: " + item);
            notFull.signalAll();
            return item;
        } finally {
            lock.unlock();
        }
    }
}

锁的最佳实践

  1. 优先使用synchronized,简单场景足够
  2. 需要高级功能时使用ReentrantLock
  3. 读多写少场景使用ReadWriteLock
  4. 始终在finally中释放锁
  5. 避免嵌套锁导致死锁

总结

Java锁机制是保证线程安全的重要手段。理解synchronized和ReentrantLock的使用场景,能帮助你编写安全高效的并发代码。