并发vs并行,同步vs异步,很多Java高级工程师也讲不清楚

发布时间:2024年01月21日


1. 引言

在当今的软件开发领域,充分利用多核处理器的能力是至关重要的。Java作为一种强大的编程语言,在并发编程方面提供了丰富的支持。本文将深入探讨Java并发编程的基础概念,为读者建立坚实的理解基础

2. 并发与并行的深度理解

2.1 并发的概念

并发是指系统同时执行多个独立的任务,这些任务在时间上有重叠,但在任意时刻只有一个任务在执行。这有助于提高系统的吞吐量和资源利用率。

在Java中,我们可以通过多线程和多进程来实现并发。

2.2 并行的概念

并行是指系统同时执行多个任务,每个任务在不同的处理器核心上执行。这通过充分利用多核处理器的能力来提高整体计算性能。

在Java中,并行通常通过并发执行的多线程来实现。

3. 进程与线程的区别

3.1 进程的基本概念

进程是独立执行的程序,每个进程都有自己的内存空间、资源和执行环境。进程之间相互独立,一个进程的崩溃不会影响其他进程。

在Java中,可以使用ProcessBuilder类创建并控制进程。

import java.io.IOException;

public class ProcessExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        ProcessBuilder processBuilder = new ProcessBuilder("echo", "Hello, World!");
        Process process = processBuilder.start();
        int exitCode = process.waitFor();
        System.out.println("Process exited with code " + exitCode);
    }
}

3.2 线程的基本概念

线程是进程内的执行单元,共享相同的内存空间和资源。线程之间可以方便地共享数据,但也需要谨慎处理同步和互斥问题。

在Java中,线程可以通过继承Thread类或实现Runnable接口来创建。

public class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running");
    }

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

3.3 进程与线程的对比

  • 内存空间、资源分配等方面的对比:

进程有独立的内存空间,相互隔离,线程共享进程的内存空间。

进程需要更多的资源,线程更轻量。

  • 使用场景的差异:

进程适用于独立、互不影响的任务,线程适用于需要共享数据的并发任务。

4. 同步与异步的深入研究

4.1 同步编程的概念

同步编程是指任务按照顺序依次执行,一个任务的完成是下一个任务开始的前提。在Java中,可以使用synchronized关键字或ReentrantLock实现同步。

public class SynchronizationExample {
    private int count = 0;

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

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

        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    example.increment();
                }
            });
            thread.start();
            thread.join();
        }

        System.out.println("Count: " + example.count);
    }
}

4.2 异步编程的概念

异步编程是指任务可以并行执行,一个任务的执行不会阻塞其他任务。在Java中,可以使用Future和Callable接口、CompletableFuture等机制实现异步编程。

import java.util.concurrent.*;

public class AsynchronousExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        Future<String> future = executor.submit(() -> {
            // 异步任务的代码
            System.out.println("Asynchronous task is running");
            return "Task Result";
        });

        executor.shutdown();

        String result = future.get(); // 阻塞等待异步任务完成
        System.out.println("Result: " + result);
    }
}

4.3 同步与异步的优缺点对比

  • 同步的优缺点:

优点: 简单易理解,便于调试。

缺点: 容易造成程序阻塞,影响性能。

  • 异步的优缺点:

优点: 提高系统吞吐量,更好地利用资源。

缺点: 复杂度较高,可能引入回调地狱。

5. 线程的生命周期详解

5.1 新建状态(New)

创建线程但未启动的阶段。

public class NewStateExample {
    public static void main(String[] args) {
        Thread thread = new Thread();
        System.out.println("Thread state: " + thread.getState());
    }
}

5.2 就绪状态(Runnable)

线程被启动但尚未分配到CPU的状态。

public class RunnableStateExample {
    public static void main(String[] args) {
        Thread thread = new Thread();
        thread.start();
        System.out.println("Thread state: " + thread.getState());
    }
}

5.3 运行状态(Running)

线程正在执行的状态。

public class RunningStateExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("Thread is running");
        });
        thread.start();
    }
}

5.4 阻塞状态(Blocked)

线程被阻塞等待某条件的状态。

public class BlockedStateExample {
    private static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 1 acquired lock");
                try {
                    // 模拟耗时操作
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 2 acquired lock");
            }
        });

        thread1.start();
        thread2.start();
        Thread.sleep(500);
        System.out.println("Thread 1 state: " + thread1.getState());
        System.out.println("Thread 2 state: " + thread2.getState());
    }
}

5.5 等待状态(Waiting)

线程等待某条件的状态。

public class WaitingStateExample {
    private static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
        Thread.sleep(1000);
        System.out.println("Thread state: " + thread.getState());
    }
}

5.6 超时等待状态(Timed Waiting)

具有超时时间的等待状态。

public class TimedWaitingStateExample {
    private static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            synchronized (lock) {
                try {
                    lock.wait(1000); // 等待1秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
        Thread.sleep(500);
        System.out.println("Thread state: " + thread.getState());
    }
}

5.7 终止状态(Terminated)

线程执行完毕或异常终止的状态。

public class TerminatedStateExample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            System.out.println("Thread is running");
        });

        thread.start();
        thread.join();
        System.out.println("Thread state: " + thread.getState());
    }
}

6. 结论

本文深入讨论了Java并发编程的基础概念,包括并发与并行、进程与线程的区别,以及同步与异步编程的概念。我们还详细解释了线程的生命周期,为读者朋友建立了对Java并发编程基础的全面理解。

文章来源:https://blog.csdn.net/wcwmsj/article/details/135727267
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。