Java基础:彻底搞懂Java多线程
前言
多线程作为Java重要的特性,其重要性不言而喻。本文将从以下几个方面系统讲解Java多线程的知识,包括:
- 什么是多线程
- 线程的状态
- 创建线程的方式
- 线程池
- 线程同步与锁
- 并发编程相关类
- 示例
什么是多线程
多线程即在一个程序中同时运行多个线程,这些线程可以并发执行。在Java中,用Thread类、Runnable接口以及Executor框架来实现多线程。
多线程的好处在于可以充分利用CPU资源,并且可以提高程序的响应速度、解决一些复杂的任务,比如Web服务器中可以处理多个请求。
线程的状态
Java线程一般有以下五种状态:
- 新建(New):线程创建后,尚未启动。
- 运行(Runnable):线程正在Java虚拟机中运行的状态。
- 阻塞(Blocked):等待监视器锁、IO等操作导致线程暂停执行的状态。
- 等待(Wait):进入该状态的线程需要等待其他线程的一些操作,比如join()方法、sleep()方法等。等待期间该线程不会持有CPU资源,处于阻塞状态。
- 终止(Terminated):线程执行完毕或被强制终止的状态。
创建线程的方式
继承Thread类实现
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("This is MyThread");
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start(); // 启动线程
}
实现Runnable接口实现
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("This is MyRunnable");
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start(); // 启动线程
}
实现Callable接口实现(可以获取返回值)
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "This is MyCallable";
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable = new MyCallable();
FutureTask<String> futureTask = new FutureTask<>(myCallable);
Thread thread = new Thread(futureTask);
thread.start(); // 启动线程
String result = futureTask.get(); // 获取返回值
System.out.println(result);
}
线程池
线程池可以节省线程启动和销毁的开销,从而提升程序性能。
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executor.execute(new MyTask());
}
executor.shutdown();
线程同步与锁
当多个线程同时访问同一资源时容易出现问题,为了避免线程安全问题,需要用到线程同步和锁。
以下是使用synchronized实现同步:
public synchronized void add(int num) {
this.count += num;
}
以下是使用Lock接口实现同步:
Lock lock = new ReentrantLock();
public void add(int num) {
lock.lock();
try {
this.count += num;
} finally {
lock.unlock();
}
}
并发编程相关类
Java并发编程相关类主要包括:
- CountDownLatch:倒计时门闩
- CyclicBarrier:循环栅栏
- Semaphore:信号量
- BlockingQueue:阻塞队列等
示例
以下是一个简单的生产者和消费者示例,使用阻塞队列来保证线程安全:
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(10);
Producer producer = new Producer(blockingQueue);
Consumer consumer = new Consumer(blockingQueue);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
}
static class Producer implements Runnable {
private BlockingQueue<Integer> blockingQueue;
Producer(BlockingQueue<Integer> blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
blockingQueue.put(i);
System.out.println("生产: " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Consumer implements Runnable {
private BlockingQueue<Integer> blockingQueue;
Consumer(BlockingQueue<Integer> blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
int num = blockingQueue.take();
System.out.println("消费: " + num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
以上就是Java多线程的一些基础知识,希望能对大家有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java基础:彻底搞懂java多线程 - Python技术站