美文网首页
Java多线程

Java多线程

作者: 会九卦的兔子 | 来源:发表于2018-07-30 00:00 被阅读0次

    一、为什么有使用多线程进行编程的好处?   

        1、资源率:可以充分利用系统资源。

        2、性能上:设计良好的并发编程可以减少程序的响应时间、提高程序应答效率、降低业务系统的代码开发复杂度。

    二、并发编程的坏处?

        资源方面需要消耗更多的系统资源,线程在切换、管理堆栈,变量空间方面就需更多额外的资源来控制, 在功能测试方面会增加复杂度,如果出现不好的代码会导致修复方面的复杂度大大增加。

    三、什么是进程、线程?

        进程指的是负责整个程序的运行,程序通信进行数据调集的一次运行活动,也是系统进行资源分配和调度的基本单位,是操作系统结构的基础。

        线程指的是进程中的一个基础组成单元,一个进程可拥有多个线程

    四、单线程是什么 ?

        在一个程序中,我们启动一个进程,只有一个主线程 main线程,外界发起请求调用需要串行的响应,一次请求未完成则会阻塞后面的数据请求。

    五、多线程又是什么?

        在一个程序中,我们启动一个进程,使用多条线程同时进行业务数据的交互。

    六、多线程开发(并发编程)需要注意的是什么?

        1、线程安全性:在多线程的环境下,我们对共享成员变量等数据进行访问和数值修改是需要同步通知、在各个调用共享变量的线程实时更新,所以我们需要使用到Java的同步机制。

        2、性能问题:

            线程上下文切换不可过于频繁, 如果上下文切换频繁,CPU花在上下文切换上的时间占比就会上升,而真正处理任务的时间占比就会下降。

            要设计良好的并发程序,否则在响应时间、系统利用率、吞吐率、代码响应灵敏度造成极大的错误

             应当尽量减少程序中的线程数量,如果可以的话,可尝试无锁并发编程。

             要避免死锁,第一不要在一条线程中嵌套使用多个锁,第二不要在一条线程中嵌套占用多个计算机资源;第三最好给锁和资源加超时时间;如果你非要在一条线程中嵌套使用多个锁或占用多个资源,那你需要给锁、资源加超时时间,从而避免无限期的等待。

    七、Java 并发编程的实现方式有哪些?

        1、继承Thread的方式

                线程类继承Thread类,调用start()方法来启动线程,真正实现了多线程运行。实现run()方法来调用你的业务代码。

        2、声明实现 Runnable接口的方式

                Runnable接口的实现类,并重写其中的run方法。run()方法的方法体线程执行体

            a、Thread方式,使用synchronized关键字。

            synchronized关键字可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。

            应用于普通同步方法时,锁是当前实例对象;静态同步方法时,锁是当前类的class对象;同步方法块,锁是括号里面的对象。

    运行的结果:

    从结果来看: 多线程的情况下,貌似synchronized没起作用。 

    为什么尼?因为上面每个线程都 new SynchronizedTest() 这是五个不同的对象,所以可以多线程同时运行synchronized方法或代码段。实际上,synchronized(this)以及非static的synchronized方法,只能防止多个线程同时执行同一个对象的同步代码段。

    所以synchronized锁住的是括号里的对象,而不是代码。那么对于非static的synchronized方法,锁的就是对象本身也就是this。

    所以使用synchronized关键字的时候,应当尽量缩小代码块的应用范围,可以再代码片段中加同步就不要扩展到方法上面去,而且对于整体多线程来说 代码片段锁定的时间上来说也会相应的缩短了一些。

    结果上看就是完成了同步

    因为你需要锁的是对象,同步就完成了。那么也可以这样做

    也可以达到一样的效果。

    使用静态方法的话

    也可以达到一样的效果。

    二、实现Runnable的方式的多线程

            synchronzied关键字它不能尝试获取锁,也不响应中断,还可能会死锁。不过,相比显式锁,synchronized简单易用,JVM也可以不断优化它的实现,应该被优先使用。显式锁是相对于synchronized隐式锁而言的,它可以实现synchronzied同样的功能,但需要程序员自己创建锁,调用锁相关的接口,主要接口是Lock,主要实现类是ReentrantLock。

    相比synchronized,显式锁支持以非阻塞方式获取锁、可以响应中断、可以限时、可以指定公平性、可以解决死锁问题,这使得它灵活的多。

    在读多写少、读操作可以完全并行的场景中,可以使用读写锁以提高并发度,读写锁的接口是ReadWriteLock,实现类是ReentrantReadWriteLock。

    二、使用volatile关键字 

            被 volatile 修饰的共享变量:

            第一它保证了不同线程对这个变量进行读取时的可见性,也就是解决了可见性问题。含义大概就是一个线程修改了某个变量的值,修改后的这个新值对于其他调用它的线程来说是立即被通知到,所以是可见的。

            第二它禁止进行指令重排序, 阻止编译器对代码的优化。 加入 volatile 关键字时, 编译器在生成字节码时,会在指令序列中插入内存屏障, 会多出一个 lock 前缀指令。 内存屏障是解决禁止指令重排序和可见性问题。

    结果是:

    相关文章

      网友评论

          本文标题:Java多线程

          本文链接:https://www.haomeiwen.com/subject/lcqrmftx.html