您的位置:

Java多线程编程实践

Java多线程编程是Java程序员必须要掌握的一项技能。在现代计算机中,CPU核心数量不断增加,多线程编程可以充分利用CPU资源,提高程序的执行效率。本文将从线程基础、线程同步、线程池、并发数据结构和Java8并发API等方面介绍Java多线程编程实践,并给出完整的代码示例。

一、线程基础

线程是操作系统最小的调度单位,它是进程的一个执行单元。Java线程可以通过继承Thread类或实现Runnable接口来创建。以下是一个继承Thread类的示例:

public class MyThread extends Thread {
    public void run() {
        // 线程执行方法
    }
}

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

以上代码创建了一个继承Thread类的MyThread类,并在main方法中启动了该线程。

除了继承Thread类创建线程外,还可以通过实现Runnable接口来创建线程,以下是一个实现Runnable接口的示例:

public class MyRunnable implements Runnable {
    public void run() {
        // 线程执行方法
    }
}

public class Test {
    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

以上代码创建了一个实现Runnable接口的MyRunnable类,并在main方法中启动了该线程。

二、线程同步

Java多线程编程中,由于多个线程同时访问共享资源,容易出现线程安全问题。线程同步是解决线程安全问题的一种常用方法。

Java提供了多种线程同步机制,如synchronized关键字、Lock、Semaphore等。synchronized关键字是Java中最常用的线程同步机制,它可以修饰方法或代码块。

以下是一个使用synchronized关键字进行线程同步的示例:

public class MyRunnable implements Runnable {
    private int count = 0;

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

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

    public int getCount() {
        return count;
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable runnable = new MyRunnable();
        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println(runnable.getCount());
    }
}

以上代码创建了一个使用synchronized关键字进行线程同步的MyRunnable类,并在main方法中启动了两个该线程,最终计算出count的值并输出。

三、线程池

Java中线程池是管理线程的一种机制,可以避免频繁创建和销毁线程的开销,提高程序的执行效率。

Java提供了ThreadPoolExecutor类实现线程池的功能。ThreadPoolExecutor类中的参数可以控制线程池中同时存在的线程数量、线程池中的线程空闲时间等。

以下是一个使用ThreadPoolExecutor类实现线程池的示例:

public class MyRunnable implements Runnable {
    private int count = 0;

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

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

    public int getCount() {
        return count;
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        MyRunnable runnable = new MyRunnable();
        for (int i = 0; i < 5; i++) {
            executorService.execute(runnable);
        }
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.out.println(runnable.getCount());
    }
}

以上代码创建了一个使用ThreadPoolExecutor类实现线程池的MyRunnable类,并在main方法中启动了5个该线程,最终计算出count的值并输出。

四、并发数据结构

Java提供了多种并发数据结构,如ConcurrentHashMap、ConcurrentLinkedDeque等,它们可以在多线程环境中高效地操作共享资源。

ConcurrentHashMap是一个线程安全的哈希表,允许同时进行读写操作。以下是一个使用ConcurrentHashMap的示例:

public class MyRunnable implements Runnable {
    private Map map;
    private String key;

    public MyRunnable(Map
    map, String key) {
        this.map = map;
        this.key = key;
    }

    public void run() {
        for (int i = 0; i < 1000000; i++) {
            map.put(key, map.getOrDefault(key, 0) + 1);
        }
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Map
     map = new ConcurrentHashMap<>();
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.execute(new MyRunnable(map, "key1"));
        executorService.execute(new MyRunnable(map, "key2"));
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.out.println(map);
    }
}

    
   
  

以上代码创建了两个线程,对一个ConcurrentHashMap中的key进行100万次的递增操作,最终输出map的值。

五、Java8并发API

Java8增加了很多新的API来支持并发编程,如并行流、CompletableFuture等。

以下是一个使用并行流的示例:

public class Test {
    public static void main(String[] args) {
        List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        int sum = list.parallelStream().mapToInt(Integer::intValue).sum();
        System.out.println(sum);
    }
}

  

以上代码创建了一个List并使用parallelStream()方法将其转化为一个并行流,对流中的每个元素进行递增操作,并最终求和并输出。

除了并行流外,Java8也提供了CompletableFuture类来实现异步编程。以下是一个使用CompletableFuture的示例:

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture future = CompletableFuture.supplyAsync(() -> "Hello ")
                .thenApplyAsync(s -> s + "world")
                .thenApplyAsync(String::toUpperCase);
        System.out.println(future.get());
    }
}

  

以上代码使用CompletableFuture实现了一个异步执行的任务,并在每个异步任务完成后对其结果进行处理,最终输出处理后的结果。