Juc

3 篇文章

ReentrantReadWriteLock

在前面的文章中,我们深入探讨了 ReentrantLock​,它是一个功能强大的独占锁。但在很多业务场景中,读操作的频率远远高于写操作。如果此时仍然使用 ReentrantLock,即使是多个读线程之间互不影响,它们也必须排队等待,这无疑大大降低了并发性能。

5 分钟阅读
2141 字

sychronized与锁升级

在高并发编程领域,线程安全是一个绕不开的话题。Java 通过 synchronized 关键字为我们提供了一种简单易用的内置锁机制,用于保证共享数据在多线程环境下的原子性、可见性和有序性。然而,凡事有利必有弊,锁在带来数据安全的同时,也可能成为性能的瓶颈。

19 分钟阅读
9283 字

ThreadPoolExecutor

为什么我们需要线程池?

我们通常这样创建一个线程来执行任务:

  • 继承Thread
public class ThreadPoolExecutorDemo {

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();

        System.out.println("主线程结束");
    }

    static class MyThread extends Thread{

        @Override
        public void run() {
            System.out.println("this is MyThread");
        }
    }
}
  • 实现Runnable
public class ThreadPoolExecutorDemo {

    public static void main(String[] args) {

        //1. 使用匿名内部类的写法
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("子线程t0");
            }
        });
        t0.start();

        //2. 使用lambda表达式的写法
        Thread t1 = new Thread(()->{
            System.out.println("这是子线程t1");
        });
        t1.start();

        System.out.println("主线程结束");
    }


}
  • 实现Callable
public class ThreadPoolExecutorDemo {

    public static void main(String[] args) {

        //把Callable对象传给FutureTask
        FutureTask<String> futureTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                return "子线程futuretask";
            }
        });

        Thread t3 = new Thread(futureTask);
        t3.start();

        //这里是个阻塞方法,会等待子线程返回result后,主线程才会继续执行
        try {
            String result = futureTask.get();
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("主线程结束");
    }


}

32 分钟阅读
15803 字