随笔分类 - java并发编程
摘要:运行结果: 现在来模拟下,基于以上代码,锁是否可重入: 分析以上运行结果: 线程1调用a方法,第一次进入lock方法,去获取锁。此时,isLocked为false,于是将标志锁改为true。然后,输出a。再去执行b方法。此时,再次去调用lock方法。lock方法是使用 synchronized修饰的
        阅读全文
            
摘要:保证线程安全演进: synchronized volatile AtomicInteger Lock接口提供的方法: void lock():加锁 void unlock():解锁 void lockInterruptibly():在多个线程并发获取锁的时候,那么,当有些线程拿不到锁时会等待,会不停
        阅读全文
            
摘要:原子更新基本类型 原子更新数组 原子更新抽象类型 原子更新字段 原子更新基本类型: 运行结果: 运行结果: 对CAS的源码理解:--初步理解 在AtomicInteger中有这样一段源码: 其中,compareAndSwap就是CAS的缩写。如果prev和next不相等,则返回true。否则,返回f
        阅读全文
            
摘要:volatile:称之为轻量级锁,被volatile修饰的变量,在线程之间是可见的。 可见:一个线程修改了这个变量的值,在另一个线程中能够读取到这个修改后的值。 synchronized除了线程之间互斥之外,还有一个非常大的作用,就是保证可见性。以下demo即保证a值的可见性。 首先来看demo: 
        阅读全文
            
摘要:运行结果: 控制台一直在运行,但是无任何输出。 通过命令检测是否真的发生了死锁: 点击线程,检测死锁:
        阅读全文
            
摘要:自旋锁,自己在不停的旋转,旋的是CPU的时间片,也就是空转CPU。当另外一个线程没有执行结束时,它一直在自旋等待。它会一直等待另外的线程执行完毕。 运行结果: 全部执行完毕Thread-0开始执行...Thread-1开始执行...Thread-1执行完毕了Thread-0执行完毕了 以上结果明显,
        阅读全文
            
摘要:运行结果: 以上结果说明,线程A在释放方法a的同步锁之前,是可以重新获得b方法的同步锁的。同一个线程拿到同一个对象的锁,它是可以进入另一个同步方法的,这就是锁的重入。以上代码仅仅是同一个线程在一个同步方法中去成功调用另一个同步方法,并且,锁的是同一个实例。那么,不同的线程拿同一把对象去加锁,会怎样进
        阅读全文
            
摘要:理论层面: 内置锁与互斥锁 修饰普通方法、修饰静态方法、修饰代码块 demo如下: jvm层面: 查看xx方法同步代码块字节码: 查看同步方法字节码: 任何对象都可以作为锁,那么锁信息又存在对象的什么地方呢? 存在对象头中。 对象头中的信息: Mark Word Class Metadata Add
        阅读全文
            
摘要:先看代码: 运行结果: 发现,有个实例是Singleton2@1c208db1,也就说明,返回的不是同一个实例。这就是所谓的线程安全问题。 解释原因:对于以上代码注释部分,如果此时有两个线程,线程A执行到1处,读取了instance为null,然后cpu就被线程B抢去了,此时,线程A还没有对inst
        阅读全文
            
摘要:先看代码: 运行结果: 所谓的饿汉模式:不管是否使用到instance这个实例,我们都在创建的过程中就对它进行实例化。 那么,饿汉模式是否会出现线程安全问题呢? 出现线程安全问题需要满足三个条件: 1.多线程的环境下 2.必须有共享资源 3.对资源进行非原子性操作 根据以上代码,我们发现,使用饿汉式
        阅读全文
            
摘要:先看代码: 运行结果:仔细发现,出现了两个84,但代码想要的结果是,每个线程每次执行,就在原来的基础上加一。因此,这里就是线程的安全问题。 解释原因: return value++; 通过字节码分析,它其实不是原子操作,value = value + 1;首先,要先读取value的值,然后再对val
        阅读全文
            
摘要:饥饿与公平: 1.高优先级吞噬所有低优先级的CPU时间片 2.线程被永久堵塞在一个等待进入同步块的状态 3.等待的线程永远不被唤醒 关于优先级,编程的时候注意: 不要假定高优先级的线程一定先于低优先级的线程,不要有逻辑依赖线程优先级,否则可能有意外错误。因为,不同的平台,对于同一个优先级的数值,可能
        阅读全文
            
摘要:1.线程安全性问题 2.性能问题:线程上下文切换,带来一定的性能损耗。 3.活跃性问题:死锁、饥饿、活锁。 a.死锁: A对象有a1资源,B对象有b1资源。A对象必须先获得b1资源才可以使用a1资源,而B对象必须先获得a1资源才可以使用b1资源。它们互相想要对方的资源,但是又不肯释放自己拥有的资源。
        阅读全文
            
摘要:运行结果: 如果想计算集合中数字的和,也可以使用lambda表达式实现: 运行结果:
        阅读全文
            
摘要:指定一个线程任务,指定何时执行,指定每隔多久执行一次。其中,任务TimerTask是实现了Runnabe接口的。 运行结果:
        阅读全文
            
摘要:1.继承Thread类 2.实现Runnable接口 3.匿名内部类的方式 4.带返回值的线程 5.定时器 6.线程池的实现 7.Lambda表达式实现 8.Spring实现多线程
        阅读全文
            
摘要:通过继承Thread类的子类或者实现Runnable接口的匿名内部类方式启动线程: 输出结果: 思考: 如果同时使用这两种匿名内部类方式实现,是调用睡的呢? 输出结果: 对以上代码的解释: 在代码中,很明显,有一个子类thread继承了Thread,通过子类thread可以启动线程;同时,这个子类t
        阅读全文
            
摘要:输出结果: 源码解读: 1.Thread类:根据以下代码知道,我们传入的runnable参数最后是赋值给了Thread类的属性target。 2.调用start方法启动线程 3.Thread类就去找run方法: 4.于是,调用了我们runnable接口中重写的run方法。输出:
        阅读全文
            
 
                    
                     
                    
                 
                    
                
 
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号