线程的基本概念
线程(Thread)是操作系统能够进行运算调度的最小单位。它是系统进行计算的基础,被包含在进程之中,是进程中的实际运作单位。Java中的线程是CPU调度的基本单位,是操作系统进行任务调度和执行的基础。
线程的状态
在Java中,线程有六种状态,分别是:
- 新建(New):线程对象被创建后尚未启动的状态。
- 就绪(Runnable):线程对象创建后,调用start()方法,线程被调度进入就绪状态。此时线程等待被分配CPU资源。
- 运行(Running):线程获得CPU资源,开始执行。
- 阻塞(Blocked):线程因为某些原因(如等待获取锁)无法获得CPU资源,此时处于阻塞状态。
- 等待(Waiting):线程在等待某个特定条件成立,如线程调用Object.wait()方法,此时线程处于等待状态。
- 终止(Terminated):线程完成任务或被其他线程强制结束,进入终止状态。
线程的创建与启动
Java提供了两种创建线程的方法:
- 继承Thread类:通过继承Thread类并重写run()方法来创建线程。
- 实现Runnable接口:通过实现Runnable接口来创建线程,然后将线程对象交给Thread类来处理。
以下是一个通过继承Thread类创建线程的示例代码:
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running...");
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
线程同步与并发控制
在多线程环境下,由于线程共享同一块内存,所以可能会出现数据不一致或资源竞争等问题。为了避免这些问题,Java提供了线程同步机制。
同步方法
在Java中,可以使用synchronized关键字来同步方法。当一个线程进入同步方法时,它会先获取到对象的监视器锁,其他线程如果也想进入这个同步方法,必须等待锁被释放后才能获取到锁。
以下是一个同步方法的示例代码:
public class SyncThread {
public synchronized void syncMethod() {
System.out.println("Thread " + Thread.currentThread().getName() + " is running...");
}
public static void main(String[] args) {
SyncThread syncThread = new SyncThread();
Thread t1 = new Thread(() -> syncThread.syncMethod());
Thread t2 = new Thread(() -> syncThread.syncMethod());
t1.start();
t2.start();
}
}
线程安全的数据结构
Java提供了许多线程安全的数据结构,如Vector、ArrayList、CopyOnWriteArrayList、ConcurrentHashMap等。
以下是一个使用ConcurrentHashMap的示例代码:
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapExample {
private static final ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
public static void main(String[] args) {
map.put("key1", 1);
map.put("key2", 2);
System.out.println("map: " + map);
}
}
线程通信
线程之间的通信可以使用wait()、notify()和notifyAll()方法实现。
以下是一个线程通信的示例代码:
public class ThreadCommunication {
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("T1 is waiting for lock...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T1 has got the lock and continues to run...");
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
System.out.println("T2 is waiting for lock...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T2 has got the lock and continues to run...");
}
});
t1.start();
t2.start();
}
}
高效并发编程技巧
- 避免不必要的同步:尽量减少同步块的使用,可以使用其他并发工具,如
java.util.concurrent包中的工具。 - 合理使用线程池:线程池可以有效地管理线程资源,提高程序性能。
- 使用并发工具:Java提供了许多并发工具,如
CountDownLatch、CyclicBarrier、Semaphore等,可以简化并发编程。
以上是Java线程入门必知的内容,希望对您有所帮助。在后续的学习中,您还需要深入学习更多并发编程的高级知识,如原子操作、锁策略、线程池等。
