您的位置:

Java多线程编程基础

一、线程的定义和基本概念

线程是计算机科学中的一种概念,指的是在单个程序中同时进行多个任务的能力。Java中的线程是轻量级的进程。线程拥有自己的执行堆栈,但共享同一进程中的其他线程所使用的内存。Java中线程的实现主要借助Thread类和Runnable接口等形式。

在Java中,多线程的实现和使用包含以下几个基本概念:

1) 线程的启动:使用Thread的start()方法启动线程。

public class MyThread extends Thread {
    public void run() {
        // 线程逻辑代码
    }
}
MyThread myThread = new MyThread();
myThread.start(); // 启动线程

2) 线程的状态:一个线程可以处于5种状态,在Java中用枚举类Thread.State表示,包括New、Runnable、Blocked、Waiting和Terminated。

3) 线程的同步:Java提供了多种同步机制,比如synchronized关键字、ReentrantLock、CountDownLatch等等,来保证多线程访问共享资源时的线程安全。

4) 线程的通信:Java提供了多种线程通信的方法,比如wait()、notify()、notifyAll()等等,来实现线程之间的信息传递。

二、线程的创建和启动

Java中创建和启动一个线程有两种方式,分别是继承Thread类和实现Runnable接口。继承Thread类要重写run()方法,实现Runnable接口要实现其run()方法,不管哪种方式都需要调用start()方法启动线程。下面给出继承Thread类的代码示例:

public class MyThread extends Thread {
    public void run() {
        // 线程逻辑代码
    }
}
MyThread myThread = new MyThread();
myThread.start(); // 启动线程

下面给出实现Runnable接口的代码示例:

public class MyRunnable implements Runnable {
    public void run() {
        // 线程逻辑代码
    }
}
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start(); // 启动线程

三、线程的状态

Java中线程的状态包括:New、Runnable、Blocked、Waiting和Terminated。下面对这5种状态进行详细说明:

1) New:表示线程已经被创建,但还没有被启动。

2) Runnable:表示线程正在运行或者等待分配CPU时间片。

3) Blocked:表示线程等待获取一个锁,进入同步代码块等待锁。

4) Waiting:表示线程进入等待状态,等待其他线程调用notify()或notifyAll()方法来唤醒该线程。

5) Terminated:表示线程已经完成了工作,不再运行。

四、线程的同步

在Java中线程同步是很重要的一个概念,用来保证多线程对共享资源的访问的线程安全。Java提供了多种同步机制,在这里介绍两种常用的同步机制:synchronized关键字和ReentrantLock。

1) synchronized关键字

Java中synchronized关键字可以用来修饰方法或代码块来实现同步,如下面代码所示:

public synchronized void testMethod() {
    // 线程安全逻辑代码
}
synchronized (this) {
    // 线程安全逻辑代码
}

2) ReentrantLock

ReentrantLock是Java中另一种 也称为可重入锁的同步机制,同样用来保证多线程对共享资源的访问的线程安全。使用ReentrantLock锁需要先创建锁对象,然后在需要同步的代码块中调用lock()方法获得锁,执行完同步代码块后,需要调用unlock()方法释放锁。下面给出ReentrantLock锁的示例代码:

ReentrantLock lock = new ReentrantLock();
lock.lock(); // 获取锁
try {
    // 线程安全逻辑代码
} finally {
    lock.unlock(); // 释放锁
}

五、线程的通信

Java中线程的通信主要依靠wait()、notify()、notifyAll()方法实现。其中wait()方法会让执行此方法的线程释放锁,进入等待状态,等待其他线程唤醒它。notify()和notifyAll()方法则分别用来唤醒一个或所有等待锁的线程。下面给出一个简单的示例,两个线程交替打印A、B:

public class PrintThread implements Runnable {
    private int count = 0;
    private Object lock = new Object();
    public void run() {
        while (count < 10) {
            synchronized (lock) {
                System.out.print(Thread.currentThread().getName());
                count++;
                lock.notify();
                try {
                    if (count < 10)
                        lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
PrintThread printThread = new PrintThread();
new Thread(printThread, "A").start();
new Thread(printThread, "B").start();

六、线程池

Java中线程池是用于管理线程的一个机制,它可以预先创建多个线程并将它们保存在一个池中,当需要执行任务时,直接从池中获取一个线程来执行任务。使用线程池的好处在于:可以减少创建和销毁线程的开销,提高系统的性能和稳定性。Java提供了一些线程池的实现类,比如ThreadPoolExecutor。

下面给出ThreadPoolExecutor的示例代码:

ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(10));
for (int i = 1; i <= 10; i++) {
    int finalI = i;
    executor.execute(() -> {
        System.out.println(Thread.currentThread().getName() + " 执行任务 " + finalI);
    });
}

  

七、线程安全的集合类

Java中的集合类在多线程的环境中很容易出现问题。为了解决这个问题,Java提供了一些线程安全的集合类,比如ConcurrentHashMap、CopyOnWriteArrayList等等。

下面给出CopyOnWriteArrayList的示例代码:

CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
list.add("item1");
list.add("item2");
list.add("item3");
Iterator
    iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
    list.add("item4");
}

   
  

八、总结

本文主要讲解了Java多线程编程的基础知识,包括线程的定义和基本概念、线程的创建和启动、线程的状态、线程的同步、线程的通信、线程池以及线程安全的集合类等等。掌握这些基础知识,有助于我们更好地理解和应用多线程编程。