从零开始写多线程

news/2024/10/21 13:27:24
1. Java 多线程的基本概念
1.1 线程与进程
进程:是操作系统分配资源的基本单位,每个进程都有独立的内存空间。
线程:是进程内的一个执行单元,同一进程中的线程共享进程的内存空间,线程间的通信更为高效。
1.2 线程的好处
提高系统响应性:可以实现用户界面与后台处理的并发执行,使得程序即使在处理耗时操作时也能保持响应。
提高性能:充分利用多核处理器的能力,同时处理多个任务。
2. 创建线程的两种方式
2.1 继承 Thread 类
可以通过继承 Thread 类并重写 run() 方法来创建线程。1class MyThread extends Thread {
2    @Override
3    public void run() {
4        System.out.println("Thread running...");
5    }
6    
7    public static void main(String[] args) {
8        MyThread thread = new MyThread();
9        thread.start(); // 启动线程
10    }
11}
2.2 实现 Runnable 接口
也可以实现 Runnable 接口,并将其实例作为参数传递给 Thread 的构造函数。1class MyRunnable implements Runnable {
2    @Override
3    public void run() {
4        System.out.println("Runnable running...");
5    }
6    
7    public static void main(String[] args) {
8        Thread thread = new Thread(new MyRunnable());
9        thread.start();
10    }
11}
3. 线程的生命周期
线程的生命周期包括以下几个阶段:新建 (NEW):当一个线程对象被创建但尚未启动时。
就绪 (RUNNABLE):线程被启动后,等待 CPU 时间片。
运行 (RUNNABLE):线程获得了 CPU 时间片并开始执行。
阻塞 (BLOCKED):线程因等待某种条件(如 I/O 操作或同步锁)而暂时停止运行。
等待/休眠 (WAITING):线程因等待特定事件的发生(如 wait() 方法)而暂停运行。
定时等待 (TIMED_WAITING):线程因等待一定时间(如 sleep() 方法)而暂停运行。
终止 (TERMINATED):线程执行完毕或被异常终止。
4. 线程同步
4.1 同步锁
为了保证多线程环境下对共享资源的正确访问,可以使用同步锁(Synchronized)来保护临界区。1public class Counter {
2    private int count = 0;
3    
4    public synchronized void increment() {
5        count++;
6    }
7    
8    public synchronized int getCount() {
9        return count;
10    }
11}
4.2 volatile 关键字
volatile 关键字可以用来标记一个变量是共享的,确保了对变量的可见性和禁止指令重排。1public class Counter {
2    private volatile int count = 0;
3    
4    public void increment() {
5        count++;
6    }
7    
8    public int getCount() {
9        return count;
10    }
11}
4.3 Lock 接口
Lock 接口提供了更灵活的锁定机制,可以实现更复杂的同步策略。1import java.util.concurrent.locks.Lock;
2import java.util.concurrent.locks.ReentrantLock;
3
4public class Counter {
5    private int count = 0;
6    private final Lock lock = new ReentrantLock();
7    
8    public void increment() {
9        lock.lock();
10        try {
11            count++;
12        } finally {
13            lock.unlock();
14        }
15    }
16    
17    public int getCount() {
18        return count;
19    }
20}
5. 线程间通信
5.1 wait() 和 notify()
wait() 和 notify() 方法可以用来实现线程间的通信。1public class Counter {
2    private int count = 0;
3    private final Object monitor = new Object();
4    
5    public void increment() {
6        synchronized (monitor) {
7            count++;
8            monitor.notify();
9        }
10    }
11    
12    public void decrement() {
13        synchronized (monitor) {
14            while (count == 0) {
15                try {
16                    monitor.wait();
17                } catch (InterruptedException e) {
18                    e.printStackTrace();
19                }
20            }
21            count--;
22        }
23    }
24}
5.2 生产者-消费者模式
生产者-消费者模式是一种经典的线程协作模型,通过队列来实现生产者和消费者之间的解耦。1import java.util.concurrent.BlockingQueue;
2import java.util.concurrent.LinkedBlockingQueue;
3
4public class ProducerConsumerDemo {
5    private static final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
6    
7    public static void main(String[] args) {
8        Thread producer = new Thread(() -> {
9            try {
10                for (int i = 0; i < 100; i++) {
11                    queue.put(i);
12                    System.out.println("Produced: " + i);
13                }
14            } catch (InterruptedException e) {
15                e.printStackTrace();
16            }
17        });
18        
19        Thread consumer = new Thread(() -> {
20            try {
21                for (int i = 0; i < 100; i++) {
22                    int item = queue.take();
23                    System.out.println("Consumed: " + item);
24                }
25            } catch (InterruptedException e) {
26                e.printStackTrace();
27            }
28        });
29        
30        producer.start();
31        consumer.start();
32    }
33}
6. 线程池
线程池可以有效地管理线程,避免频繁创建和销毁线程所带来的开销。1import java.util.concurrent.ExecutorService;
2import java.util.concurrent.Executors;
3
4public class ThreadPoolDemo {
5    public static void main(String[] args) {
6        ExecutorService executor = Executors.newFixedThreadPool(5);
7        
8        for (int i = 0; i < 10; i++) {
9            executor.submit(() -> {
10                System.out.println(Thread.currentThread().getName() + " is running");
11            });
12        }
13        
14        executor.shutdown();
15    }
16}
7. 线程中断
线程中断是一种通知线程终止的方式。1public class ThreadInterruptDemo {
2    public static void main(String[] args) throws InterruptedException {
3        Thread thread = new Thread(() -> {
4            try {
5                while (!Thread.currentThread().isInterrupted()) {
6                    Thread.sleep(1000);
7                    System.out.println("Running...");
8                }
9            } catch (InterruptedException e) {
10                System.out.println("Interrupted!");
11                Thread.currentThread().interrupt(); // 重置中断标志
12            }
13        });
14        
15        thread.start();
16        Thread.sleep(5000);
17        thread.interrupt();
18    }
19}
8. 线程安全的容器
Java 提供了一些线程安全的容器类,如 Vector、ConcurrentHashMap 等。1import java.util.concurrent.ConcurrentHashMap;
2
3public class ThreadSafeContainerDemo {
4    private static ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
5    
6    public static void main(String[] args) {
7        Thread t1 = new Thread(() -> {
8            for (int i = 0; i < 100; i++) {
9                map.put(i, "Value " + i);
10            }
11        });
12        
13        Thread t2 = new Thread(() -> {
14            for (int i = 0; i < 100; i++) {
15                map.remove(i);
16            }
17        });
18        
19        t1.start();
20        t2.start();
21    }
22}

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/74152.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

mybatis的一对多,多对一,以及多对多的配置和使用

根据这个应用场景,我们需要获取在查询一个用户信息的时候还要去读取这个用户发布的帖子 现在我们来看一看用户级联文章在JavaBean中的编写方式,这就是一对多在JavaBean中的配置现在我们再来看一看Mybatis的Mapper该如何编写一对多?很简单,就是在resultMap标签中配置<collec…

PbootCMS执行SQL发生错误(DISK I/O ERROR)怎么办

执行SQL发生错误(DISK I/O ERROR)问题描述:PBootCMS网站程序提示“执行 SQL 发生错误!错误:DISK I/O ERROR”。 解决方案:检查磁盘空间:确保服务器磁盘空间充足,没有满。 检查磁盘健康:使用磁盘检测工具检查磁盘健康状况,确保没有坏道。 优化数据库:优化数据库表,修…

K个节点翻转链表

概述 起因:leetcode题目 25. K 个一组翻转链表 问题描述 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。 k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节…

PbootCMS登录后无法使用数据备份功能,备份失败或提示错误怎么办

问题描述:登录后无法使用数据备份功能,备份失败或提示错误。 解决方案:检查文件权限:确保备份目录具有可写权限。 检查数据库连接:确保数据库连接配置正确,数据库服务正常运行。 检查PHP错误日志:查看服务器的PHP错误日志,查找可能的错误信息。 清除缓存:清除浏览器缓…

一文彻底弄清Redis的布隆过滤器

布隆过滤器(Bloom Filter)是一种空间效率极高的数据结构,用于快速判断一个元素是否在集合中。它能够节省大量内存,但它有一个特点:可能存在误判,即可能会认为某个元素存在于集合中,但实际上不存在;而对于不存在的元素,它保证一定不会误判。布隆过滤器适合在对存储空间…

PbootCMS登录后无法上传文件怎么办

登录后无法上传文件问题描述:登录后无法上传文件,提示上传失败。 解决方案:检查文件权限:确保上传目录(如upload/)具有可写权限(通常为755或777)。 检查PHP配置:确保PHP的文件上传设置正确,特别是upload_max_filesize和post_max_size。 检查防火墙和安全设置:确保服…

PbootCMS登录页面无法正常加载,显示为空白页或错误信息怎么办

问题描述:登录页面无法正常加载,显示为空白页或错误信息。 解决方案:检查Web服务器配置:确保Web服务器(如Apache、Nginx)配置正确,特别是虚拟主机配置。 检查PHP配置:确保PHP配置正确,特别是php.ini文件中的设置。 检查文件权限:确保PBootCMS相关目录和文件的权限设置…

PbootCMS登录后立即被注销怎么办

登录后立即被注销问题描述:登录后立即被注销,无法保持登录状态。 解决方案:检查Cookie设置:确保浏览器的Cookie设置正确,允许PBootCMS设置Cookie。 检查会话设置:确保PHP的会话设置正确,特别是session.cookie_lifetime和session.gc_maxlifetime。 检查防火墙和安全设置:…