java线程复习(1)

本文详细对比了Java中的进程与线程概念,解释了它们在资源分配、执行效率、通信方式上的区别,深入探讨了锁机制、可重入锁、volatile变量与synchronized关键字的差异,以及wait()与notify()方法的使用场景。

Java 进程与线程的对比

  • 进程是资源分配的最小单位,线程是程序执行的最小单位,是系统独立调度和分派 CPU 的基本单位
  • 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此 CPU 切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多,线程的上下文切换的性能消耗要小于进程。
  • 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行

我们所说的锁其实是对象锁,对于static修饰的方法,锁定的是该类所有的对象,也就是说共享一个锁,而对于非static方法,则一个对象一把锁

两个对象二把锁
public class MultiThread {

    private int num = 200;

    public synchronized void printNum(String threadName) {
      
            num = num - 100;
            System.out.println(threadName + " num="+num);
        
       
    }

    public static void main(String[] args) throws InterruptedException {
        final MultiThread multiThread1 = new MultiThread();
        final MultiThread multiThread2 = new MultiThread();

        new Thread(new Runnable() {
            public void run() {
                multiThread1.printNum("thread1");
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                multiThread2.printNum("thread2");
            }
        }).start();
    }
}
//static修饰的方法后
public class MultiThread {

   static private int num = 200;

    static public synchronized void printNum(String threadName) {
      
            num = num - 100;
            System.out.println(threadName + " num="+num);
        
       
    }

    public static void main(String[] args) throws InterruptedException {
        final MultiThread multiThread1 = new MultiThread();
        final MultiThread multiThread2 = new MultiThread();

        new Thread(new Runnable() {
            public void run() {
                multiThread1.printNum("thread1");
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                multiThread2.printNum("thread2");
            }
        }).start();
    }
}

可重入锁

  • 关键字 Synchronized 拥有锁重入的功能,也就是在使用 Synchronized 的时候,当一个线程得到一个对象的锁后,在该锁里执行代码的时候可以再次请求该对象的锁时可以再次得到该对象的锁。

  • 也就是说,当线程请求一个由其它线程持有的对象锁时,该线程会阻塞,而当线程请求由自己持有的对象锁时,如果该锁是重入锁,请求就会成功,否则阻塞。

  • 可重入锁的目的就是避免自己调用自己的同步方法时,出现死锁现象

volatile变量 与 synchronize的区别

  • 关键字 volatile 是线程同步的轻量级实现,性能比 synchronized 要好,并且 volatile 只能修于变量,而 synchronized 可以修饰方法,代码块等
  • 多线程访问 volatile 不会发生阻塞,而 synchronized 会发生阻塞。
  • 可以保证数据的可见性,但不可以保证原子性,而 synchronized 可以保证原子性,也可以间接保证可见性,因为他会将私有内存和公共内存中的数据做同步。
  • volatile 光靠可加性,并不能实现线程安全,而synchronize可以实现线程安全

wait()方法 和 notify()方法对比

  • wait() 和 notify() 方法要在同步块或同步方法中调用,即在调用前,线程也必须获得该对象的对象级别锁。

  • wait 方法是立即释放锁, notify 方法之后,当前线程不会立即释放其拥有的该对象锁,而是notify()所在方法执行完之后才会释放该对象锁,被通知的线程也不会立即获得对象锁,而是等待notify()所在方法执行完之后,释放了该对象锁,才可以获得该对象锁。

  • notify 每次唤醒 wait 等待状态的线程都是随机的,且每次只唤醒一个。

  • notifAll 每次唤醒 wait 等待状态的线程使之重新竞争获取对象锁,优先级最高的那个线程会最先执行。

  • 当线程处于 wait() 状态时,调用线程对象的 interrupt() 方法会出现 InterruptedException 异常。

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值