CAS

keycloak集成cas客户端

♀尐吖头ヾ 提交于 2020-04-26 19:07:51
keycloak作为cas客户端背景 1.keycloak本身不支持Cas协议,考虑到市场上使用Cas-Server做认证的企业较多,将keycloak与Cas-server进行集成,相当于keycloak作为cas的客户端。 2.采用三方支持的方式,让keycloak支持cas客户端 3.keycloak集成cas客户端后,cas-server回调keycloak 4.keycloak初始化session缓存等信息。 5.其他应用利用已经登录的用户信息通过鉴权。 keycloak集成Cas-client,提供间接访问Cas-server的支持,实现与第三方鉴权服务的集成。步骤如下: 1.提供keycloak集成Cas客户端的SPI 2.打包并部署到keycloak中 3.安装并启动Cas-Server 4.提供keycloak配置Cas服务端参数配置的html页面 5.keycloak中配置cas服务端的相关参数 6.测试客户端通过keycloak间接访问Cas-server,实现同一个realm下的SSO. 若有开发需要,可留言于我,或者加入 QQ:794868111 ,相互交流。 PS:keycloak与cas-client的集成稍微我会上传到github中,请后续关注。 来源: oschina 链接: https://my.oschina.net/u/4340671

一道非常棘手的 Java 面试题:i++ 是线程安全的吗?

安稳与你 提交于 2020-04-26 15:17:13
i++ 是线程安全的吗? 相信很多中高级的 Java 面试者都遇到过这个问题,很多对这个不是很清楚的肯定是一脸蒙逼。内心肯定还在质疑,i++ 居然还有线程安全问题?只能说自己了解的不够多,自己的水平有限。 先来看下面的示例来验证下 i++ 到底是不是线程安全的。 1000个线程,每个线程对共享变量 count 进行 1000 次 ++ 操作。 上面的例子我们期望的结果应该是 1000000,但运行 N 遍,你会发现总是不为 1000000,至少你现在知道了 i++ 操作它不是线程安全的了。 先来看 JMM 模型中对共享变量的读写原理吧。 每个线程都有自己的工作内存,每个线程需要对共享变量操作时必须先把共享变量从主内存 load 到自己的工作内存,等完成对共享变量的操作时再 save 到主内存。 问题就出在这了,如果一个线程运算完后还没刷到主内存,此时这个共享变量的值被另外一个线程从主内存读取到了,这个时候读取的数据就是脏数据了,它会覆盖其他线程计算完的值。。。 这也是经典的内存不可见问题,那么把 count 加上 volatile 让内存可见是否能解决这个问题呢? 答案是:不能。因为 volatile 只能保证可见性,不能保证原子性。多个线程同时读取这个共享变量的值,就算保证其他线程修改的可见性,也不能保证线程之间读取到同样的值然后相互覆盖对方的值的情况。

原子类的ABA问题

依然范特西╮ 提交于 2020-04-26 12:13:30
原子类AtomicInteger的ABA问题 连环套路 从AtomicInteger引出下面的问题 CAS -> Unsafe -> CAS底层思想 -> ABA -> 原子引用更新 -> 如何规避ABA问题 ABA问题是什么 狸猫换太子 假设现在有两个线程,分别是T1 和 T2,然后T1执行某个操作的时间为10秒,T2执行某个时间的操作是2秒,最开始AB两个线程,分别从主内存中获取A值,但是因为B的执行速度更快,他先把A的值改成B,然后在修改成A,然后执行完毕,T1线程在10秒后,执行完毕,判断内存中的值为A,并且和自己预期的值一样,它就认为没有人更改了主内存中的值,就快乐的修改成B,但是实际上 可能中间经历了 ABCDEFA 这个变换,也就是中间的值经历了狸猫换太子。 所以ABA问题就是,在进行获取主内存值的时候,该内存值在我们写入主内存的时候,已经被修改了N次,但是最终又改成原来的值了 CAS导致ABA问题 CAS算法实现了一个重要的前提,需要取出内存中某时刻的数据,并在当下时刻比较并替换,那么这个时间差会导致数据的变化。 比如说一个线程one从内存位置V中取出A,这时候另外一个线程two也从内存中取出A,并且线程two进行了一些操作将值变成了B,然后线程two又将V位置的数据变成A,这时候线程one进行CAS操作发现内存中仍然是A,然后线程one操作成功

深入理解Java虚拟机(自动内存管理机制)

烈酒焚心 提交于 2020-04-26 05:47:53
文章首发于公众号: BaronTalk 书籍真的是常读常新,古人说「书读百遍其义自见」还是很有道理的。周志明老师的这本《深入理解 Java 虚拟机》我细读了不下三遍,每一次阅读都有新的收获,每一次阅读对 Java 虚拟机的理解就更进一步。因而萌生了将读书笔记整理成文的想法,一是想检验下自己的学习成果,对学习内容进行一次系统性的复盘;二是给还没接触过这部好作品的同学推荐下,在阅读这部佳作之前能通过我的文章一窥书中的精华。 原想着一篇文章就够了,但写着写着就发现篇幅大大超出了预期。看来还是功力不够,索性拆成了六篇文章,分别从 自动内存管理机制 、 类文件结构 、 类加载机制 、 虚拟机执行引擎 、 程序编译与代码优化 、 高效并发 六个方面来做更加细致的介绍。本文先说说 Java 虚拟机的自动内存管理机制。 一. 运行时数据区 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有些区域随着虚拟机进程的启动而存在,有些区域则是依赖线程的启动和结束而建立和销毁。Java 虚拟机所管理的内存被划分为如下几个区域: 程序计数器 程序计数器是一块较小的内存区域,可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令

[kuangbin带你飞]专题二十一 概率&期望 部分题解

隐身守侯 提交于 2020-04-26 05:32:39
2018-03-08 18:02:20 A - A Dangerous Maze LightOJ - 1027 题意: 小花的迷宫入口有n个门 走每个门的概率都是相同的 每个门有一个值x x可正可负 正代表x 分钟后可以征服迷宫 负代表|x|分钟之后小花会回到原点 问征服迷宫时间的期望 题解:假设小花平均E分钟可以征服迷宫 如果小花刚开始选择了一个值为负的门 那么此时的时间变成了E+|Xi| 概率为1/n 因为选择每个门的概率都相同 PS:相当于在原来可以出去的基础上浪费了|Xi|分钟 如果小花刚开始选择了一个值为正的门 那么此时的时间变成了Xi 概率为1/n 因为选择每个门的概率都相同 假设值为正的门有n0个 值为负的门有n1个 正的门的值的总和为T0 负的门的值的总和为|T1| 则 E = T0/n + (E+|Xi|)/n*n1 = T0/n + |T1|/n + E/n*n1 n0/n*E = (T0+|T1|)/n E = (T0 + |T1|) / n0 刚接触概率与期望 感谢 http://blog.csdn.net/jinglinxiao/article/details/70226889 代码如下: #include<stdio.h> #include<iostream> #include<algorithm> using namespace std; int t;

ReentrantLock 源码分析

北城以北 提交于 2020-04-26 01:54:36
前言 上一篇文章 ReentrantLock 源码分析 - 基础篇 对 AbstractQueuedSynchronizer ( AQS ) 的相关 概念 和 作用 作了简要介绍, 本文将继续对 AQS 做进一步介绍 ( 基于 jdk1.8 源码 )。 阅读之前需要了解什么是 共享锁 和 独占锁 . 正文 上一篇有提到 CountDownlatch, ReentrantLock, ReentrantReadWriteLock 等并发包工具类都是基于 AQS 实现的, 这要求 AQS 需要提供很 丰富 并且 通用 的功能, 比如: ReentranLock 是独占锁, 而 ReentrantReadWriteLock 是共享锁, 他们分别调用 AQS 的 acquire 方法去获取独占资源, acquireShared 方法去获取共享资源。但是又共同调用了 compareAndSetState 方法去实现 CAS 操作。 这还只是这两个类的之间的区别, 而 java.util.concurrent 包下面有诸多工具类, 因此, 我们暂时没必要全面了解 AQS 的所有功能 那么, 接下来就着重分析 AQS 在 ReentrantLock 的作用。 先来看一张 AQS 的类图 从图中可以看出 : AQS 继承自 AbstractOwnableSynchronizer AQS 有两个内部类

【并发编程】Java并发编程传送门

心已入冬 提交于 2020-04-25 16:31:37
本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。 并发编程系列博客传送门 背景知识 【并发编程】摩尔定律失效“带来”并行编程 【并发编程】Java对并发编程的支持历史 【并发编程】并发编程中你需要知道的基础概念 并发编程基础 【并发编程】实现多线程的几种方式 【并发编程】Thread类的详细介绍 【并发编程】Object的wait、notify和notifyAll方法 【并发编程】线程状态解析 【并发编程】ThreadLocal其实很简单 【并发编程】InheritableThreadLocal使用详解 JMM相关 【并发编程】最简单的 Java内存模型 讲解 【并发编程】Java内存模型之原子性问题 【并发编程】Java内存模型之可见性问题 【并发编程】Java内存模型之有序性问题 【并发编程】Volatile原理和使用场景解析 【并发编程】ThreadLocalRandom——Random在大并发环境下的替代者 锁技术 【并发编程】锁分类介绍 【并发编程】synchronized的使用场景和原理简介 【转载】并发编程的基石——AQS类 【并发编程】同步锁——ReentrantLock 原子操作类 【并发编程】并发编程的基石——CAS机制 【转载】Atomic系列类整体介绍 【并发编程

深入浅出 JVM GC(4)常用 GC 参数介绍

妖精的绣舞 提交于 2020-04-25 06:34:54
# 前言 从前面的3篇文章中,我们分析了5个垃圾收集器,还有一些 GC 的算法,那么,在 GC 调优中,我们肯定会先判断哪里出现的问题,然后再根据出现的问题进行调优,而调优的手段就是 JVM 提供给我们的那些参数或者说选项,这些参数将会改变 GC 的运行方式。因此,他们显得极为重要。 我们将每一个垃圾收集器相关的参数一个一个娓娓道来,注意,楼主推荐一个小程序:前阿里 JVM 大神寒泉子的公众号里面有个小程序------JVM Pocket,这个小程序介绍了所有的 JVM 参数的作用,你可以在里面搜索你想知道的参数,也可以把你了解的参数写上去供大家参考。公众号:lovestblog。 值得注意的一点是,这些参数可能会重复,还记得我们之前的那张图吗,楼主觉得有必要再发一次: 可以看到,这些收集器会有一些重复,而且,某些参数也是会作用于所有的处理器,因此,我们下面的介绍可能会有一些重复。 还有一点就是,JVM 为我们设置了很多默认的参数,但是,如果可以的话,还是建议使用显式的声明,这样更能表达意图。否则,别人不一定知道我们是否知道这些默认值。 我们开始我们的参数之旅吧! # 1. Serial 收集器参数 串行收集器,client 的默认收集器,分为年轻代 Serial 和老年代 Serial Old 收集器。 -XX:+UseSerialGC

java面试-synchronized底层实现机制

旧城冷巷雨未停 提交于 2020-04-25 06:20:27
一、synchronized的三种应用方式 1、修饰实例方法,锁是当前实例对象,进入同步代码前要获得当前实例的锁 /** * synchronized修饰实例方法,当前线程的锁是实例对象accountingSync * 当一个线程正在访问一个对象的synchronized实例方法,那么其他线程不能访问该对象的其他synchronized方法 * 一个对象只有一把锁 */ public class AccountingSync implements Runnable { static AccountingSync accountingSync = new AccountingSync(); //共享资源 static int i = 0; static int j = 0; public synchronized void increase() { i++; } @Override public void run() { for(int i =0;i<1000000;i++){ synchronized (this){ increase(); } } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(accountingSync);

14 Java虚拟机实现 synchronized

旧时模样 提交于 2020-04-25 04:34:20
java 中的 synchronized 运行 在 Java 中,我们经常用 synchronized 关键字对程序进行加锁。无论是一个代码块还是静态方法或者实例方法,都可以直接用 synchronized 声明。 当声明 synchronized 代码块时,编译的字节码将包含 monitorenter 和 monitorexit 指令。这两种指令均会消耗操作数栈上的一个引用类型的元素,作为所要加锁解锁的锁对象。 public void foo(Object lock) { synchronized (lock) { lock.hashCode(); } } // 上面的 Java 代码将编译为下面的字节码 public void foo(java.lang.Object); Code: 0: aload_1 1: dup 2: astore_2 3: monitorenter 4: aload_1 5: invokevirtual java/lang/Object.hashCode:()I 8: pop 9: aload_2 10: monitorexit 11: goto 19 14: astore_3 15: aload_2 16: monitorexit 17: aload_3 18: athrow 19: return Exception table: from to