跳转至

多线程编程:线程基础

1. 线程的概念

在Java中,线程是程序执行的最小单元。一个进程可以包含多个线程,每个线程可以独立执行不同的任务。多线程编程允许程序同时执行多个任务,从而提高程序的效率和响应性。

1.1 什么是线程?

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

1.2 线程与进程的区别

  • 进程:进程是操作系统分配资源的基本单位,每个进程都有独立的内存空间。
  • 线程:线程是进程中的一个执行路径,多个线程共享进程的内存空间。

2. 创建线程的方法

在Java中,创建线程主要有两种方式: 1. 继承 Thread 类 2. 实现 Runnable 接口

2.1 继承 Thread

通过继承 Thread 类并重写 run() 方法来创建线程。

// 示例1:继承Thread类
class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行的代码
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();

        // 启动线程
        thread1.start();
        thread2.start();
    }
}

代码解释: - MyThread 类继承了 Thread 类,并重写了 run() 方法。 - start() 方法用于启动线程,线程启动后会执行 run() 方法中的代码。 - Thread.currentThread().getName() 获取当前线程的名称。

2.2 实现 Runnable 接口

通过实现 Runnable 接口并实现 run() 方法来创建线程。

// 示例2:实现Runnable接口
class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的代码
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread1 = new Thread(myRunnable);
        Thread thread2 = new Thread(myRunnable);

        // 启动线程
        thread1.start();
        thread2.start();
    }
}

代码解释: - MyRunnable 类实现了 Runnable 接口,并实现了 run() 方法。 - 创建 Thread 对象时传入 Runnable 实例。 - start() 方法启动线程,线程启动后会执行 run() 方法中的代码。

2.3 使用匿名内部类创建线程

可以使用匿名内部类来简化线程的创建。

// 示例3:使用匿名内部类创建线程
public class AnonymousThreadExample {
    public static void main(String[] args) {
        // 使用匿名内部类创建线程
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " - " + i);
                }
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " - " + i);
                }
            }
        });

        // 启动线程
        thread1.start();
        thread2.start();
    }
}

代码解释: - 使用匿名内部类直接实现 Runnable 接口,并重写 run() 方法。 - 创建 Thread 对象时传入匿名内部类的实例。 - start() 方法启动线程。

3. 线程的生命周期

线程在其生命周期中会经历以下几种状态: 1. 新建(New):线程对象被创建,但尚未启动。 2. 就绪(Runnable):线程已经启动,等待CPU调度执行。 3. 运行(Running):线程正在执行 run() 方法中的代码。 4. 阻塞(Blocked):线程因为某些原因(如等待资源)暂时停止执行。 5. 终止(Terminated):线程执行完毕或异常终止。

4. 练习题

练习1:创建多个线程

编写一个程序,创建三个线程,每个线程打印自己的名称和从1到10的数字。

练习2:使用 Runnable 接口

修改练习1的程序,使用 Runnable 接口来创建线程。

练习3:线程同步

编写一个程序,创建两个线程,共享一个计数器变量。每个线程对计数器进行1000次加1操作,最终输出计数器的值。观察是否会出现线程安全问题,并尝试使用同步机制解决。

5. 总结

  • 线程是程序执行的最小单元,多个线程可以并发执行。
  • 创建线程的两种主要方式:继承 Thread 类和实现 Runnable 接口。
  • 线程的生命周期包括新建、就绪、运行、阻塞和终止状态。
  • 多线程编程可以提高程序的效率和响应性,但也需要注意线程安全问题。

通过本章的学习,你应该已经掌握了线程的基本概念和创建方法。接下来,你可以尝试编写一些多线程程序,并逐步深入理解线程同步、线程通信等高级主题。