首页 课程 师资 教程 报名

Java培训教程:Java多线程并发教程

  • 2019-12-23 14:31:27
  • 1788次 动力节点


Java培训教程:Java多线程并发教程


  多线程


  提高了程序的执行效率,多线程同时执行,因此具有不确定性


  提高了资源利用率,CPU、内存等


  占用一定的内存空间


  线程越多CPU的调度开销越大


  程序的复杂度会上升


  线程池


  避免线程的创建和销毁带来的性能开销(少开销)


  加快响应速度。任务到达时不用创建线程,直接使用线程池中的


  避免大量的线程间因互相抢占系统资源而阻塞的现象(避免阻塞)


  能对线程进行简单的管理并提供定时执行、间隔执行等功能(便于管理)


  sleep和wait


  sleep是使线程停止一段时间的方法,线程不会释放对象锁.在sleep一段时间后,线程不一定立刻回复执行


  wait是线程交互的时候,如果线程对一个同步对象发出wait调用,该线程会立刻暂停执行.进入等待状态,直到被唤醒,线程会放弃对象锁,使得其他线程可以使用同步控制块或者方法


  多线程和并发


  run和start的区别:


  调用 start() 方法才会启动新线程;如果直接调用 Thread 的 run() 方法,它的行为就会和普通的方法一样;为了在新的线程中执行我们的代码,必须使用 Thread.start() 方法。run只是thread的一个普通方法,start是真正的启一个线程


  关键字


  可见性


  可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的.也就是一个线程修改的结果。另一个线程马上就能看到

  在 Java 中 volatile、synchronized 和 final 实现可见性


  原子性


  将操作变成原子操作


  在 Java 中 synchronized 和在 lock、unlock 中操作保证原子性


  有序性


  Java 语言提供了 volatile 和 synchronized 两个关键字来保证线程之间操作的有序性


  wait和sleep


  sleep


  在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),该线程不丢失任何监视器的所属权,sleep() 是 Thread 类专属的静态方法,针对一个特定的线程。


  wait


  方法使实体所处线程暂停执行,从而使对象进入等待状态,导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒,该方法只能在同步方法中调用。


  比较


  本质的区别:sleep是线程的运行状态控制,wait是线程之间的通讯


  sleep是Thread中的方法,wait是Object中的方法


  wait() 方法进入等待状态时会释放同步锁。调用的时候需要先获得该 Object 的锁,调用 wait 后,会把当前的锁释放掉同时阻塞住。而 sleep() 方法不会释放同步锁。


  sleep让线程从运行到阻塞,wait让线程从运行到等待队列


  wait要用notify和notify唤醒,只能在同步环境中使用,sleep可以在任何环境中使用


  notify notifyall


  notify


  随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态,该方法只能在同步方法或同步块内部调用。


  notifyall


  解除所有那些在该对象上调用wait方法的线程的阻塞状态,同样该方法只能在同步方法或同步块内部调用。


  synchronized


  是一种同步锁(CPU悲观锁),java并发编程的最常用的用于保证线程安全的方式,所有加上 synchronized 的方法和块语句,在多线程访问的时候,同一时刻只能有一个线程能够访问。


  修饰实例方法


  作用于当前实例加锁,进入同步代码前要获得当前实例的锁。


  实例方法不包括静态方法


  修饰静态方法


  作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁。静态成员不专属于任何一个实例对象,是类成员,因此通过class对象锁可以控制静态成员的并发操作


  修饰代码块


  指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。


  Lock


  采用乐观锁


  能完成synchronized所实现的所有功能,Lock有比synchronized更精确的线程语义和更好的性能。Lock的锁定是通过代码实现的,而synchronized是在JVM层面上实现的,synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。Lock锁的范围有局限性,块范围,而synchronized可以锁住块、对象、类。在加锁和解锁处需要通过lock()和unlock()显示指出


  volatile


  Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。volatile 是一个特殊的修饰符,只有成员变量才能使用它。在Java并发程序缺少同步类的情况下,多线程对成员变量的操作对其它线程是透明的。volatile 变量可以保证下一个读取操作会在前一个写操作之后发生。线程都会直接从内存中读取该变量并且不缓存它。这就确保了线程读取到的变量是同内存中是一致的。


  volatile


  能保证可见性,不能保证原子性


  当对非 volatile 变量进行读写的时候,每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以拷贝到不同的 CPU cache 中。而声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步。


  轻量级的 synchronized


  Volatile变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。


  volatile 并不完全是线程安全的


  用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的值。volatile很容易被误用,用来进行原子性操作。


  访问最新值


  Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而不是从各个线程的“工作内存”。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。


  效率问题


  synchronized关键字是防止多个线程同时执行一段代码,那么就会很影响程序执行效率,而volatile关键字在某些情况下性能要优于synchronized


  volatile关键字是无法替代synchronized关键字的,因为volatile关键字无法保证操作的原子性。


  JAVA高级


  对象序列化


  很多情况下,对象内部状态是需要被持久化的,将运行中的对象状态保存下来(最直接的方式就是保存到文件系统中),在需要的时候可以还原,即使是在Java虚拟机退出的情况下


  对象序列化机制是Java内建的一种对象持久化方式,可以很容易实现在JVM中的活动对象与字节数组(流)之间进行转换,使用得Java对象可以被存储,可以被网络传输,在网络的一端将对象序列化成字节流,经过网络传输到网络的另一端,可以从字节流重新还原为Java虚拟机中的运行状态中的对象


Java培训教程:Java多线程并发教程


       以上就是动力节点Java培训机构小编介绍的“Java培训教程:Java多线程并发教程”的内容,希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为你服务。


       相关文章


  零基础怎么自学Java,完整版Java学习路线图


  你还在纠结学Java,是自学还是去培训班吗


  一个标准的Java程序员如何进阶?


  Java学习路线清单,快速进阶Java


  Java编程初学者要如何进阶


选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交