Java 学习系列(13):Java 多线程详解

Java 学习系列(13):Java 多线程详解

1. 多线程概述

在 Java 中,多线程是指同时运行多个线程的能力。线程是程序执行的基本单元,每个线程都有自己的执行路径。通过多线程,可以提高程序的并发性和执行效率,尤其是在多核 CPU 上。

Java 提供了强大的多线程支持,通过 Thread 类或实现 Runnable 接口来创建和管理线程。

2. 创建线程的方式

Java 中有两种主要的方式来创建线程:

2.1 继承 Thread

通过继承 Thread 类,并重写其 run() 方法来定义线程要执行的任务。

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程正在执行...");
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();  // 启动线程
    }
}

2.2 实现 Runnable 接口

另一种方式是实现 Runnable 接口,并将其作为参数传递给 Thread 类的构造函数。这样可以避免继承限制,使类可以同时继承其他类。

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程正在执行...");
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();  // 启动线程
    }
}

3. 线程的生命周期

Java 中线程的生命周期包括以下几个状态:

  • 新建状态(New):线程被创建,但尚未启动。
  • 就绪状态(Runnable):线程准备好执行,等待 CPU 分配时间片。
  • 运行状态(Running):线程正在执行。
  • 阻塞状态(Blocked):线程被阻塞,等待资源或条件。
  • 终止状态(Terminated):线程执行完成或被强制终止。

4. 线程同步

在多线程编程中,多个线程可能会共享同一资源,导致数据不一致。为了避免这种情况,需要使用线程同步。

4.1 synchronized 关键字

synchronized 用于修饰方法或代码块,确保同一时刻只有一个线程可以访问同步的代码块或方法。

4.1.1 同步方法
class Counter {
    private int count = 0;
    
    public synchronized void increment() {
        count++;
    }

    public synchronized void decrement() {
        count--;
    }
    
    public int getCount() {
        return count;
    }
}

public class SynchronizedExample {
    public static void main(String[] args) {
        Counter counter = new Counter();
        
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.decrement();
            }
        });

        t1.start();
        t2.start();
        
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("最终计数: " + counter.getCount());
    }
}

4.2 同步代码块

同步代码块用于在方法内对共享资源进行同步,而不是整个方法。

class Counter {
    private int count = 0;

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

    public void decrement() {
        synchronized (this) {
            count--;
        }
    }

    public int getCount() {
        return count;
    }
}

public class SynchronizedExample {
    public static void main(String[] args) {
        Counter counter = new Counter();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.decrement();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("最终计数: " + counter.getCount());
    }
}

5. 线程间通信

在多线程环境中,线程之间可以通过 线程间通信 来协作,常用的方法有 wait()notify()notifyAll()

5.1 wait()notify()

  • wait():使当前线程进入等待状态,并释放锁。
  • notify():唤醒一个等待的线程。
  • notifyAll():唤醒所有等待的线程。
class Producer implements Runnable {
    private final Object lock;

    public Producer(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            System.out.println("生产者生产产品...");
            lock.notify();  // 唤醒消费者线程
        }
    }
}

class Consumer implements Runnable {
    private final Object lock;

    public Consumer(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                lock.wait();  // 等待生产者生产产品
                System.out.println("消费者消费产品...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ThreadCommunicationExample {
    public static void main(String[] args) {
        Object lock = new Object();
        
        Thread producer = new Thread(new Producer(lock));
        Thread consumer = new Thread(new Consumer(lock));
        
        consumer.start();
        producer.start();
    }
}

6. 线程池

在多线程编程中,线程池是一种非常重要的技术,它可以避免频繁创建和销毁线程的开销,提高系统的性能和资源利用率。

6.1 使用 ExecutorService 创建线程池

import java.util.concurrent.*;

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(2);

        executor.submit(() -> System.out.println("任务 1 执行"));
        executor.submit(() -> System.out.println("任务 2 执行"));
        
        executor.shutdown();  // 关闭线程池
    }
}

7. 总结

  • 线程的创建:可以通过继承 Thread 类或实现 Runnable 接口来创建线程。
  • 线程同步:使用 synchronized 来保证线程的安全访问,避免竞态条件。
  • 线程间通信:通过 wait()notify()notifyAll() 方法实现线程之间的协作。
  • 线程池:线程池是管理多线程的有效方式,使用 ExecutorService 来管理线程池。

下一期:《Java 学习系列(14):Java 集合框架详解》

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值