取消与关闭
任务和线程的启动很容易。在大多数时候,我们都会让它们运行直到结束,或者让它们自行停止。然而,有时候我们希望提前结束任务或线程,或许是因为用户取消了操作,或者应用程序需要被快速关闭。
任务取消
在Java中没有一种安全的抢占式方法来停止线程,因此也就没有安全的抢占式方法来停止任务。只有一些协作式的机制,使请求取消的任务和代码都遵循一种协商好的协议。
1 | private volatile boolean cancelled; |
这篇文章我们来讲一下如何集成JWT到Spring Boot项目中来完成接口的权限验证。
JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT作为一个开放的标准( RFC 7519 ),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
如何使用JWT?
在身份鉴定的实现中,传统方法是在服务端存储一个session,给客户端返回一个cookie,而使用JWT之后,当用户使用它的认证信息登陆系统之后,会返回给用户一个JWT,用户只需要本地保存该token(通常使用local storage,也可以使用cookie)即可。
在构建文件的并发程序时,必须正确地使用线程和锁,但这些终归只是一些机制。要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的和可变的状态的访问。一个对象是否是线程安全的,取决于它是否被多个线程同时访问。当多个线程访问某个状态变量并且其中有一个线程执行写入操作时,必须采用同步机制来协同这些线程对变量的访问。Java中的主要同步机制是关键字synchronized,它提供了一种独占的加锁方式,但「同步」这个术语还包括volatile类型的变量,显式锁以及原子变量。
如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误。有三种方式可以修复这个问题:
当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。在线程安全类中封装了必要的同步机制,因此客户端无须进一步采取同步措施。
无状态对象一定是线程安全的。(没有共享数据)
在看完了《深入理解Java虚拟机》之后,继续看《Java并发编程实战一书》。
相信在了解虚拟机之后,再来看并发相关知识,能理解得更透彻,书中也讲到,对Java内存模型理解得越深入,就对并发编程掌握得越好。顺道说一下,关于JDK里线程和并发相关类的使用,我主要是通过《Think in Java》学习的,这里就不再介绍基本使用方法了。
线程也被称为轻量级进程(这一部分在《深入理解Java虚拟机》中提到过,点击查看)。在大多数现代操作系统中, 都是以线程为基本的调度单位,而不是进程。
要想充分发挥多处理器系统的强大计算能力,线程可以有效的降低程序的开发和维护成本,同时提升复杂应用程序的性能。
「内存模型」可以理解为在特定的操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。
Java虚拟机规范中试图定义一种Java内存模型来屏蔽掉各种硬件和操作系统内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。在此之前,主流程序语言(如C/C++等)直接使用物理硬件和操作系统的内存模型,因此,会由于不同平台上内存模型的差异,有可能导致程序在一套平台上并发完全正常,而在另外一台平台上并发访问却经常出错,因此在某些场景就必须针对不同的平台来编写程序。
Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量与Java编程中所说的变量有所区别,它包括了实例字段、静态字段和构成数组对象的元素,但不包括局部变量与方法参数,因为后者是线程私有的,不会被共享,自然不存在竞争问题。
Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的私有工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。(这很好的诠释了volatile关键字的作用和原理)