一、线程的定义和基本概念
线程是计算机科学中的一种概念,指的是在单个程序中同时进行多个任务的能力。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的示例代码:
CopyOnWriteArrayListlist = 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多线程编程的基础知识,包括线程的定义和基本概念、线程的创建和启动、线程的状态、线程的同步、线程的通信、线程池以及线程安全的集合类等等。掌握这些基础知识,有助于我们更好地理解和应用多线程编程。