Java并发包是Java中提供的一个用于支持多线程编程的工具包。Java并发包提供了多种机制来控制线程的执行,保证线程的安全性和可靠性。下面我们将介绍Java并发包的使用方法,并给出示例。
Java并发包中的 Lock 和 Condition 接口提供了一种更为灵活的同步机制。与 synchronized 不同的是,它们可以支持更为细粒度的锁控制,并且可以避免死锁问题。
下面是一个使用 Lock 和 Condition 接口的示例代码:
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 的示例代码:
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
接口提供了对读取操作和写入操作进行分离的机制,从而提高了并发性能。Semaphore
和 CountDownLatch
类提供了不同类型的信号量和计数器,可以用于控制线程的并发访问和同步。