java并发编程(七)

2023-03-21 21:19:33 浏览数 (1)

  1. 线程池

线程池是一种管理和复用线程的机制,它可以避免频繁创建和销毁线程的开销,提高程序的性能和稳定性。Java提供了Executor框架来支持线程池的实现,常用的实现类有ThreadPoolExecutor和ScheduledThreadPoolExecutor。

示例代码:

代码语言:java复制
// 创建一个固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
// 提交任务到线程池
executor.submit(new Runnable() {
    @Override
    public void run() {
        // 执行任务代码
    }
});
// 关闭线程池
executor.shutdown();
  1. 线程间通信

线程间通信是多线程编程中常用的一种机制,它可以使线程之间协调工作,实现数据共享和同步操作。Java提供了多种实现线程间通信的方式,包括wait/notify、Lock/Condition、CountDownLatch、CyclicBarrier等。

示例代码:

代码语言:java复制
// 使用wait/notify实现线程间通信
class MyThread extends Thread {
    private Object lock;
    public MyThread(Object lock) {
        this.lock = lock;
    }
    public void run() {
        synchronized(lock) {
            try {
                System.out.println("Thread waiting...");
                lock.wait();
                System.out.println("Thread resumed...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
Object lock = new Object();
MyThread t = new MyThread(lock);
t.start();
Thread.sleep(1000);
synchronized(lock) {
    lock.notify();
}
  1. 线程安全

线程安全是指在多线程环境下,程序能够正确地处理并发访问共享资源的问题,保证程序的正确性和可靠性。Java提供了多种实现线程安全的方式,包括synchronized关键字、Lock接口、Atomic类、Concurrent包等。

示例代码:

代码语言:java复制
// 使用synchronized实现线程安全
class Counter {
    private int value;
    public synchronized void increment() {
        value  ;
    }
    public int getValue() {
        return value;
    }
}
Counter c = new Counter();
for (int i = 0; i < 10; i  ) {
    new Thread(() -> {
        for (int j = 0; j < 1000; j  ) {
            c.increment();
        }
    }).start();
}
Thread.sleep(1000);
System.out.println(c.getValue());
  1. 原子操作

原子操作是指一组操作要么全部执行成功,要么全部执行失败,能够保证操作的原子性和可见性。Java提供了多种实现原子操作的类,包括AtomicInteger、AtomicBoolean、AtomicReference等。

示例代码:

代码语言:java复制
// 使用AtomicInteger实现原子操作
AtomicInteger counter = new AtomicInteger();
for (int i = 0; i < 10; i  ) {
    new Thread(() -> {
        for (int j = 0; j < 1000; j  ) {
            counter.incrementAndGet();
        }
    }).start();
}
Thread.sleep(1000);
System.out.println(counter.get());
  1. 并发集合

并发集合是指在多线程环境下能够提供高效、安全、可扩展的数据结构,能够支持并发访问和修改操作。Java提供了多种实现并发集合的类,包括ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentLinkedQueue等。

示例代码:

代码语言:java复制
// 使用ConcurrentHashMap实现并发集合
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
for (int i = 0; i < 10; i  ) {
    new Thread(() -> {
        for (int j = 0; j < 1000; j  ) {
            map.put(UUID.randomUUID().toString(), j);
        }
    }).start();
}
Thread.sleep(1000);
System.out.println(map.size());
  1. 锁优化

锁优化是指通过优化锁的使用方式和粒度,来提高程序的性能和可伸缩性。Java提供了多种锁优化技术,包括锁粗化、锁消除、偏向锁、轻量级锁等。

示例代码:

代码语言:java复制
// 使用偏向锁优化锁的使用
class Counter {
    private int value;
    public void increment() {
        synchronized(this) {
            value  ;
        }
    }
    public int getValue() {
        synchronized(this) {
            return value;
        }
    }
}
Counter c = new Counter();
for (int i = 0; i < 10; i  ) {
    new Thread(() -> {
        for (int j = 0; j < 1000; j  ) {
            c.increment();
        }
    }).start();
}
Thread.sleep(1000);
System.out.println(c.getValue());
  1. AQS

AQS(AbstractQueuedSynchronizer)是Java提供的一种用于实现同步器的框架,它提供了一种基于FIFO队列的机制,能够支持独占锁和共享锁两种模式,是Java并发编程中的核心技术之一。

示例代码:

代码语言:java复制
// 使用AQS实现同步器
class MySync extends AbstractQueuedSynchronizer {
    protected boolean tryAcquire(int arg) {
        return compareAndSetState(0, 1);
    }
    protected boolean tryRelease(int arg) {
        setState(0);
        return true;
    }
}
MySync sync = new MySync();
for (int i = 0; i < 10; i  ) {
    new Thread(() -> {
        sync.acquire();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        sync.release();
    }).start();
}
  1. Fork/Join框架

Fork/Join框架是Java提供的一种用于实现分治算法的框架,它能够自动将任务分解成小块,分配给多个线程并行执行,最后将结果合并返回。Fork/Join框架是Java并发编程中的重要组件之一,能够提高程序的性能和可伸缩性。

示例代码:

代码语言:java复制
// 使用Fork/Join框架实现并行计算
class SumTask extends RecursiveTask<Long> {
    private static final int THRESHOLD = 10000;
    private long[] data;
    private int start;
    private int end;
    public SumTask(long[] data, int start, int end) {
        this.data = data;
        this.start = start;
        this.end = end;
    }
    protected Long compute() {
        if (end - start <= THRESHOLD) {
            long sum = 0;
            for (int i = start; i < end; i  ) {
                sum  = data[i];
            }
            return sum;
        } else {
            int mid = (start   end) / 2;
            SumTask left = new SumTask(data, start, mid);
            SumTask right = new SumTask(data, mid, end);
            left.fork();
            right.fork();
            return left.join()   right.join();
        }
    }
}
long[] data = new long[100000];
for (int i = 0; i < data.length; i  ) {
    data[i] = i;
}
ForkJoinPool pool = new ForkJoinPool();
SumTask task = new SumTask(data, 0, data.length);
long result = pool.invoke(task);
System.out.println(result);

以上是Java并发编程高级知识点的梳理以及代码示例,希望对您有所帮助。

0 人点赞