首页
学习
活动
专区
圈层
工具
发布

Java并发包的使用

Java并发包是Java中提供的一个用于支持多线程编程的工具包。Java并发包提供了多种机制来控制线程的执行,保证线程的安全性和可靠性。下面我们将介绍Java并发包的使用方法,并给出示例。

Lock和Condition

Java并发包中的 Lock 和 Condition 接口提供了一种更为灵活的同步机制。与 synchronized 不同的是,它们可以支持更为细粒度的锁控制,并且可以避免死锁问题。

下面是一个使用 Lock 和 Condition 接口的示例代码:

代码语言:javascript
复制
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockConditionExample {

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    private void method1() throws InterruptedException {
        lock.lock();
        try {
            System.out.println("method1 is running");
            condition.await();
            System.out.println("method1 is finished");
        } finally {
            lock.unlock();
        }
    }

    private void method2() {
        lock.lock();
        try {
            System.out.println("method2 is running");
            condition.signal();
            System.out.println("method2 is finished");
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        LockConditionExample example = new LockConditionExample();
        Thread thread1 = new Thread(() -> {
            try {
                example.method1();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread thread2 = new Thread(example::method2);
        thread1.start();
        Thread.sleep(1000);
        thread2.start();
    }
}

在上面的示例中,Lock 和 Condition 接口用于控制 method1 和 method2 方法的执行顺序。其中 method1 方法会先获取锁并进入等待状态,而 method2 方法会在一段时间后唤醒 method1 方法并释放锁。这样就可以保证 method1 方法先执行。

Semaphore

Semaphore 是一个计数信号量,用于控制同时访问某个资源的线程数。可以将 Semaphore 看作是一种计数器,每当有线程访问该资源时,计数器的值减一;当计数器的值为零时,其他线程需要等待,直到有线程释放该资源。

下面是一个使用 Semaphore 的示例代码:

代码语言:javascript
复制
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Counter {
    private int count = 0;
    private Lock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        return count;
    }
}

public class IncrementThread extends Thread {
    private Counter counter;

    public IncrementThread(Counter counter) {
        this.counter = counter;
    }

    public void run() {
        for (int i = 0; i < 1000000; i++) {
            counter.increment();
        }
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t1 = new IncrementThread(counter);
        Thread t2 = new IncrementThread(counter);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Count: " + counter.getCount());
    }
}

在这个例子中,我们创建了一个名为 Counter 的类,它具有一个 increment 方法,该方法使用 ReentrantLock 实现了同步。我们还创建了一个名为 IncrementThread 的线程类,它具有一个对 Counter 实例的引用,并且在运行时会调用 increment 方法。最后,在 Main 类中创建了两个 IncrementThread 实例,并启动它们。当它们完成时,我们打印计数器的当前值。

这个例子演示了如何使用 Lock 接口来同步线程。请注意,在 increment 方法内部,我们使用 lock 实例的 lock 方法获取锁,使用 unlock 方法释放锁。这样,当一个线程在执行 increment 方法时,其他线程必须等待锁释放后才能进入该方法。这确保了线程之间的互斥性,并确保计数器的值在多线程环境下正确地增加。

除了 ReentrantLock 之外,Java 并发包还提供了其他几种类型的锁和同步机制。例如,ReadWriteLock 接口提供了对读取操作和写入操作进行分离的机制,从而提高了并发性能。SemaphoreCountDownLatch 类提供了不同类型的信号量和计数器,可以用于控制线程的并发访问和同步。

下一篇
举报
领券