从零开始写多线程

1. Java 多线程的基本概念
1.1 线程与进程
进程:是操作系统分配资源的基本单位,每个进程都有独立的内存空间。
线程:是进程内的一个执行单元,同一进程中的线程共享进程的内存空间,线程间的通信更为高效。
1.2 线程的好处
提高系统响应性:可以实现用户界面与后台处理的并发执行,使得程序即使在处理耗时操作时也能保持响应。
提高性能:充分利用多核处理器的能力,同时处理多个任务。
2. 创建线程的两种方式
2.1 继承 Thread 类
可以通过继承 Thread 类并重写 run() 方法来创建线程。

1class MyThread extends Thread {
2    @Override
3    public void run() {
4        System.out.println("Thread running...");
5    }
6    
7    public static void main(String[] args) {
8        MyThread thread = new MyThread();
9        thread.start(); // 启动线程
10    }
11}
2.2 实现 Runnable 接口
也可以实现 Runnable 接口,并将其实例作为参数传递给 Thread 的构造函数。

1class MyRunnable implements Runnable {
2    @Override
3    public void run() {
4        System.out.println("Runnable running...");
5    }
6    
7    public static void main(String[] args) {
8        Thread thread = new Thread(new MyRunnable());
9        thread.start();
10    }
11}
3. 线程的生命周期
线程的生命周期包括以下几个阶段:

新建 (NEW):当一个线程对象被创建但尚未启动时。
就绪 (RUNNABLE):线程被启动后,等待 CPU 时间片。
运行 (RUNNABLE):线程获得了 CPU 时间片并开始执行。
阻塞 (BLOCKED):线程因等待某种条件(如 I/O 操作或同步锁)而暂时停止运行。
等待/休眠 (WAITING):线程因等待特定事件的发生(如 wait() 方法)而暂停运行。
定时等待 (TIMED_WAITING):线程因等待一定时间(如 sleep() 方法)而暂停运行。
终止 (TERMINATED):线程执行完毕或被异常终止。
4. 线程同步
4.1 同步锁
为了保证多线程环境下对共享资源的正确访问,可以使用同步锁(Synchronized)来保护临界区。

1public class Counter {
2    private int count = 0;
3    
4    public synchronized void increment() {
5        count++;
6    }
7    
8    public synchronized int getCount() {
9        return count;
10    }
11}
4.2 volatile 关键字
volatile 关键字可以用来标记一个变量是共享的,确保了对变量的可见性和禁止指令重排。

1public class Counter {
2    private volatile int count = 0;
3    
4    public void increment() {
5        count++;
6    }
7    
8    public int getCount() {
9        return count;
10    }
11}
4.3 Lock 接口
Lock 接口提供了更灵活的锁定机制,可以实现更复杂的同步策略。

1import java.util.concurrent.locks.Lock;
2import java.util.concurrent.locks.ReentrantLock;
3
4public class Counter {
5    private int count = 0;
6    private final Lock lock = new ReentrantLock();
7    
8    public void increment() {
9        lock.lock();
10        try {
11            count++;
12        } finally {
13            lock.unlock();
14        }
15    }
16    
17    public int getCount() {
18        return count;
19    }
20}
5. 线程间通信
5.1 wait() 和 notify()
wait() 和 notify() 方法可以用来实现线程间的通信。

1public class Counter {
2    private int count = 0;
3    private final Object monitor = new Object();
4    
5    public void increment() {
6        synchronized (monitor) {
7            count++;
8            monitor.notify();
9        }
10    }
11    
12    public void decrement() {
13        synchronized (monitor) {
14            while (count == 0) {
15                try {
16                    monitor.wait();
17                } catch (InterruptedException e) {
18                    e.printStackTrace();
19                }
20            }
21            count--;
22        }
23    }
24}
5.2 生产者-消费者模式
生产者-消费者模式是一种经典的线程协作模型,通过队列来实现生产者和消费者之间的解耦。

1import java.util.concurrent.BlockingQueue;
2import java.util.concurrent.LinkedBlockingQueue;
3
4public class ProducerConsumerDemo {
5    private static final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
6    
7    public static void main(String[] args) {
8        Thread producer = new Thread(() -> {
9            try {
10                for (int i = 0; i < 100; i++) {
11                    queue.put(i);
12                    System.out.println("Produced: " + i);
13                }
14            } catch (InterruptedException e) {
15                e.printStackTrace();
16            }
17        });
18        
19        Thread consumer = new Thread(() -> {
20            try {
21                for (int i = 0; i < 100; i++) {
22                    int item = queue.take();
23                    System.out.println("Consumed: " + item);
24                }
25            } catch (InterruptedException e) {
26                e.printStackTrace();
27            }
28        });
29        
30        producer.start();
31        consumer.start();
32    }
33}
6. 线程池
线程池可以有效地管理线程,避免频繁创建和销毁线程所带来的开销。

1import java.util.concurrent.ExecutorService;
2import java.util.concurrent.Executors;
3
4public class ThreadPoolDemo {
5    public static void main(String[] args) {
6        ExecutorService executor = Executors.newFixedThreadPool(5);
7        
8        for (int i = 0; i < 10; i++) {
9            executor.submit(() -> {
10                System.out.println(Thread.currentThread().getName() + " is running");
11            });
12        }
13        
14        executor.shutdown();
15    }
16}
7. 线程中断
线程中断是一种通知线程终止的方式。

1public class ThreadInterruptDemo {
2    public static void main(String[] args) throws InterruptedException {
3        Thread thread = new Thread(() -> {
4            try {
5                while (!Thread.currentThread().isInterrupted()) {
6                    Thread.sleep(1000);
7                    System.out.println("Running...");
8                }
9            } catch (InterruptedException e) {
10                System.out.println("Interrupted!");
11                Thread.currentThread().interrupt(); // 重置中断标志
12            }
13        });
14        
15        thread.start();
16        Thread.sleep(5000);
17        thread.interrupt();
18    }
19}
8. 线程安全的容器
Java 提供了一些线程安全的容器类,如 Vector、ConcurrentHashMap 等。

1import java.util.concurrent.ConcurrentHashMap;
2
3public class ThreadSafeContainerDemo {
4    private static ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
5    
6    public static void main(String[] args) {
7        Thread t1 = new Thread(() -> {
8            for (int i = 0; i < 100; i++) {
9                map.put(i, "Value " + i);
10            }
11        });
12        
13        Thread t2 = new Thread(() -> {
14            for (int i = 0; i < 100; i++) {
15                map.remove(i);
16            }
17        });
18        
19        t1.start();
20        t2.start();
21    }
22}

  

posted @ 2024-10-21 13:26  XiangdxDu  阅读(4)  评论(0编辑  收藏  举报