Java 多线程的基本概念!

举报
伴川 发表于 2024/01/02 14:48:27 2024/01/02
【摘要】 其他系列文章导航Java基础合集数据结构与算法合集设计模式合集多线程合集分布式合集ES合集文章目录其他系列文章导航文章目录前言一、进程和线程二、使用多线程的目的三、线程安全3.1 使用Atomic包下的类:3.2 使用volatile关键字:3.3 使用CountDownLatch:3.4 使用ReentrantLock:四、死锁解决前言在当今的计算机世界中,多线程编程已经成为了一种重要的技...

其他系列文章导航
Java基础合集
数据结构与算法合集
设计模式合集
多线程合集
分布式合集
ES合集
文章目录
其他系列文章导航
文章目录
前言
一、进程和线程
二、使用多线程的目的
三、线程安全
3.1 使用Atomic包下的类:
3.2 使用volatile关键字:
3.3 使用CountDownLatch:
3.4 使用ReentrantLock:
四、死锁解决
前言
在当今的计算机世界中,多线程编程已经成为了一种重要的技术,它能够充分利用多核处理器和多线程硬件的优点,提高程序的执行效率。Java作为一种流行的编程语言,也提供了丰富的多线程编程支持。
在Java中,多线程编程涉及到多个概念和机制,包括线程的创建、线程的状态、同步、并发和死锁等。这些概念和机制的学习和理解对于掌握Java多线程编程至关重要。
在接下来的文章中,我们将详细介绍Java多线程编程的基本概念和机制,并通过示例代码和案例分析帮助你更好地理解和掌握这些知识。
希望这些内容能够帮助你更好地理解和应用Java多线程编程技术,提高你的编程能力和效率。
一、进程和线程
进程:系统进行资源分配和调度的独立单位,每一个进程都有它自己的内存空间和系统资源。进程实现多处理机环境下的进程调度分派,切换时,都需要花费较大的时间和空间开销。
通俗话:为了提高系统的执行效率,减少处理机的空转时间和调度切换的时间,以及便于系统管理,所以有了线程,线程取代了进程了调度的基本功能。
简单来说,进程作为资源分配的基本单位,线程作为资源调度的基本单位。
编辑
二、使用多线程的目的
使用多线程最主要的原因是提高系统的资源利用率。
(现在CPU基本都是多核的,如果你只用单线程,那就是只用到了一个核心,其他的核心就相当于空闲在那里了)
比如说,我们系统Web服务器用的是Tomcat,Tomcat处理每一个请求都会从线程连接池里边用一个线程去处理。
又比如说,我们用连接数据库会用对应的连接池 Druid/C3PO/DBCP等等。
以下是一个简单的Java代码示例,演示了如何使用多线程来执行并发任务。
代码如下:
public class MultiThreadExample {
public static void main(String[] args) {
// 创建一个线程池
ExecutorService executor = Executors.newFixedThreadPool(10);

    // 提交多个任务到线程池  
    for (int i = 0; i < 10; i++) {  
        executor.submit(() -> {  
            // 执行任务逻辑  
            System.out.println("Task " + Thread.currentThread().getId() + " is running.");  
        });  
    }  

    // 关闭线程池  
    executor.shutdown();  
}  

}
在这个示例中,我们创建了一个固定大小的线程池,并提交了10个任务到线程池中。每个任务都会输出当前线程的ID,表示它们正在并发地执行。通过使用多线程,我们可以充分利用系统的多核资源,提高应用程序的性能。
三、线程安全
我个人解决线程安全问题的思路有以下:

  1. 能不能保证操作的原子性,考虑atomic包下的类够不够我们使用。
  2. 能不能保证操作的可见性,考虑volatile关键字够不够我们使用
  3. 如果涉及到对线程的控制 (比如一次能使用多少个线程,当前线程触发的条件是否依赖其他线程的结果),考虑CountDownLatch/Semaphore等等
  4. 如果是集合,考虑iava.util.concurrent包下的集合类
  5. 如果synchronized无法满足,考虑lock包下的类
    3.1 使用Atomic包下的类:
    代码如下:
    java`import java.util.concurrent.atomic.AtomicInteger;

public class AtomicCounter {
private AtomicInteger counter = new AtomicInteger(0);

public void increment() {  
    counter.incrementAndGet();  
}  

public int get() {  
    return counter.get();  
}  

}3.2 使用volatile关键字: 代码如下: javapublic class SharedResource {
private volatile int value;

public void setValue(int value) {  
    this.value = value;  
}  

public int getValue() {  
    return value;  
}  

}3.3 使用CountDownLatch: 代码如下: javaimport java.util.concurrent.CountDownLatch;

public class ThreadController {
private CountDownLatch latch = new CountDownLatch(3); // 初始化为3个线程

public void startThread() {  
    new Thread(() -> {  
        try {  
            latch.await(); // 等待其他线程完成  
            System.out.println("All threads completed.");  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }).start();  
}  

}`
3.4 使用ReentrantLock:
如果synchronized无法满足需求,可以考虑使用java.util.concurrent.locks包下的类,如ReentrantLock、ReentrantReadWriteLock等。这些锁类提供了更灵活的线程控制和同步机制。
代码如下:
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;

class MyResource {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private int count = 0;

public void increment() {   
    lock.lock();   
    try {   
        while (count == 5) {   
            try {   
                condition.await();   
            } catch (InterruptedException e) {   
                e.printStackTrace();   
            }   
        }   
        count++;   
        System.out.println("Count is " + count);   
        condition.signalAll();   
    } finally {   
        lock.unlock();   
    }   
}   

}
四、死锁解决
原因: 当前线程拥有其他线程需要的资源,当前线程等待其他线程已拥有的资源,都不放弃自己拥有的资源。
避免死锁的方式一般有以下方案:

  1. 固定加锁的顺序,比如我们可以使用Hash值的大小来确定加锁的先后。
  2. 尽可能缩减加锁的范围,等到操作共享变量的时候才加锁。
  3. 使用可释放的定时锁。(一段时间申请不到锁的权限了,直接释放掉)
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。