synchronized

1.2Java面试题及回答集锦

匿名 (未验证) 提交于 2019-12-02 21:53:52
1、问题:如果A和B对象循环引用,是否可以被GC? 回答:可以,现在的虚拟机基本都是通过可达性分析算法来判断对象是否存活的,而不是通过简单的引用计数法来判断对象是否存活。可达性分析算法使用一系列的“GC Roots”对象(虚拟机栈中引用的对象、静态属性引用对象)作为起始点,这些节点向下搜索的路径称为引用链,当一个对象到GC Roots没有任何引用链连接,则证明对象是不可用的。 2、Java中的内存溢出是如何造成的? OutOfMemoryError: (1)PerGern Space 程序中使用了大量jar或class,使Java虚拟机装载类空间不够。 解决方案:调参XX:PermSize 和 XX:MaxPermSize 、减少jar包,减少类的重复加载 (2)Java Heap Space Java虚拟机创建了太多的对象。 解决方案:调参Xms(初始堆大小)Xmx(最大堆大小)、检查死循环或不必要创建的重复对象 解决方案:调整JVM中线程大小。 3、 String s = “123”;这个语句有几个对象产生? 若字符串池中没有"123",则产生一个对象,并且放入常量池中,若有"123",则产生0个对象。 若是String s = new String("123"),若常量池中没有,则在常量池中创建一个,然后在堆内存中创建一个。 4、 Error

JAVA之创建线程的两种

匿名 (未验证) 提交于 2019-12-02 21:53:52
前提: 1:这两种方法都是通过重写run(),在run()方法中实现运行在线程上的代码 2:Runnable相比于Thread更适合多个相同程序代码去处理同一个资源的情况,通常采用Runnable 3:被 synchronized 修饰的方法在某一时刻只允许一个线程访问 继承Thread类创建多线程 package rjxy; /* public class Thread1 { public static void main(String[] args) { MyThread t1=new MyThread("我是线程1"); MyThread t2=new MyThread("我是线程2"); t1.start(); t2.start(); } } class MyThread extends Thread{ public MyThread() { super(); } public MyThread(String name) { super(name); } public void run(){ for (int i = 0; i <10; i++) { System.out.println(this.getName()); } } } 实现Runnable接口创建多线程 package rjxy; public class Thread2 { /* *

Java多线程学习(超详细!)

匿名 (未验证) 提交于 2019-12-02 21:53:52
ѧϰĿ¼ 一、扩展 Thread 类 二、实现 Runnable 接口 三、Thread和Runnable的区别 四、线程状态转换 五、线程调度 六、常用函数说明 使用方式 为什么要用join方法 七、常见线程名词解释 八、线程同步 九、线程数据传递 首先讲一下进程和线程的区别:   线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。   线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。   多进程是指操作系统能同时运行多个任务(程序)。   多线程是指在同一程序中有多个顺序流在执行。 在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。 一、扩展java.lang.Thread类 package com.multithread.learning; /** *@functon 多线程学习 *@author 林炳文 *@time 2015.3.9 */ class Thread1 extends Thread{ private String name; public Thread1 (String name) { this .name=name; } public void run () { for ( int i = 0 ; i < 5 ; i++) { System.out

Java面试官最爱问的volatile关键字

匿名 (未验证) 提交于 2019-12-02 21:53:32
在Java的面试当中,面试官最爱问的就是volatile关键字相关的问题。经过多次面试之后,你是否思考过,为什么他们那么爱问volatile关键字相关的问题?而对于你,如果作为面试官,是否也会考虑采用volatile关键字作为切入点呢? 爱问volatile关键字的面试官,大多数情况下都是有一定功底的,因为volatile作为切入点,往底层走可以切入Java内存模型(JMM),往并发方向走又可接切入Java并发编程,当然,再深入追究,JVM的底层操作、字节码的操作、单例都可以牵扯出来。 所以说懂的人提问题都是有门道的。那么,先整体来看看volatile关键字都设计到哪些点:内存可见性(JMM特性)、原子性(JMM特性)、禁止指令重排、线程并发、与synchronized的区别……再往深层次挖,可能就涉及到字节码、JVM等。 不过值得庆幸的是,如果你已经学习了微信公众号“程序新视界”JVM系列的文章,上面的知识点已经不是什么问题了,权当是复习了。那么,下面就以面试官提问的形式,在不看答案的情况下,尝试回答,看看学习效果如何。夺命连环问,开始…… 被volatile修饰的共享变量,就具有了以下两点特性: 保证了不同线程对该变量操作的内存可见性; 禁止指令重排序; 回答的很好,点出了volatile关键字两大特性。针对该两大特性继续深入。 该问题涉及到Java内存模型(JVM

java面试之JVM与多线程

匿名 (未验证) 提交于 2019-12-02 21:52:03
1. synchronized 和volatile的区别: 2.什么是happens-before原则? 3.线程有几种状态? 4.指令重排序 5.什么是线程安全与非线程安全? 6.类的加载与卸载? 7. synchronized与volatile的实现原理? 8.什么是类加载器? 9.什么是双亲委派模型? 10.垃圾回收机制? 11.CAS与ABA 12.乐观锁与悲观锁? 13.AQS 与lock 14.什么情况下会触发FullGC? 15.什么情况触发minorGC? 16.java1.8为什么用Metaspace(元空间)替换掉PermGen(永久代)?Metaspace保存在哪里? 17.线程池 18.对象引用有哪几种方式? 19.Java对象生命周期与类的生命周期? 20.JUC常用工具? 21.阻塞非阻塞、同步与非同步的概念? 22.wait()与sleep()方法的异同点? 23.Synchronized 和 ReentrantLock 有什么不同?各适合什么场景? 24.读写锁的适用场景?ReentrantReadWriteLock是如何实现的? 25.线程间的通信方式? 26.保证线程安全的方法有哪些? 27.如何提高多线程的并发性能? 28. ThreadLocal用来解决什么问题?ThreadLocal是如何实现的? 29.类的线程安全 30

java 理解CAS

匿名 (未验证) 提交于 2019-12-02 21:52:03
在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁(后面的章节还会谈到锁)。 锁机制存在以下问题: (1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。 (2)一个线程持有锁会导致其它所有需要此锁的线程挂起。 (3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。 volatile是不错的机制,但是volatile不能保证原子性。因此对于同步最终还是要回到锁机制上来。 独占锁是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一个更加有效的锁就是乐观锁。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。 CAS 操作 上面的乐观锁用到的机制就是CAS,Compare and Swap。 CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 非阻塞算法 (nonblocking algorithms) 一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。 现代的CPU提供了特殊的指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。

盘一盘 synchronized (一)―― 从打印Java对象头说起

匿名 (未验证) 提交于 2019-12-02 21:52:03
Java对象头的组成 值得注意的是,如果应用的对象过多,使用64位的指针将浪费大量内存。64位的JVM比32位的JVM多耗费50%的内存。 我们现在使用的64位 JVM会默认使用选项 +UseCompressedOops 开启指针压缩,将指针压缩至32位。 以64位操作系统为例,对象头存储内容图例。 |--------------------------------------------------------------------------------------------------------------| | Object Header (128 bits) | |--------------------------------------------------------------------------------------------------------------| | Mark Word (64 bits) | Klass Word (64 bits) | |--------------------------------------------------------------------------------------------------------------| | unused:25 | identity_hashcode:31

Java锁的种类

匿名 (未验证) 提交于 2019-12-02 21:45:52
1、synchronized对象同步锁: synchronized是对对象加锁,可作用于对象、方法(相当于对this对象加锁)、静态方法(相当于对Class实例对象加锁,锁住的该类的所有对象)以保证并发环境的线程安全。同一时刻只有一个线程可以获得锁。 其底层实现是通过使用对象监视器Monitor,每个对象都有一个监视器,当线程试图获取Synchronized锁定的对象时,就会去请求对象监视器(Monitor.Enter()方法),如果监视器空闲,则请求成功,会获取执行锁定代码的权利;如果监视器已被其他线程持有,线程进入同步队列等待。 2、Lock同步锁: 与synchronized功能类似,可从Lock与synchronized区别进行分析: 1、Lock可以通过tryLock()方法非阻塞地获取锁而。如果获取了锁即立刻返回true,否则立刻返回false。这个方法还有加上定时等待的重载方法tryLock(long time, TimeUnit unit)方法,在定时期间内,如果获取了锁立刻返回true,否则在定时结束后返回false。在定时等待期间可以被中断,抛出InterruptException异常。而Synchronized在获得锁的过程中是不可被中断的。 2、Lock可以通过lockInterrupt()方法可中断的获取锁,与lock()方法不同的是等待时可以响应中断

Java线程同步

匿名 (未验证) 提交于 2019-12-02 21:45:52
当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用。达到此目的的过程叫做同… 当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用。达到此目的的过程叫做同步(synchronization)。像你所看到的,Java为此提供了独特的,语言水平上的支持。 同步的关键是管程(也叫信号量semaphore)的概念。管程是一个互斥独占锁定的对象,或称互斥体(mutex)。在给定的时间,仅有一个线程可以获得管程。当一个线程需要锁定,它必须进入管程。所有其他的试图进入已经锁定的管程的线程必须挂起直到第一个线程退出管程。这些其他的线程被称为等待管程。一个拥有管程的线程如果愿意的话可以再次进入相同的管程。 如果你用其他语言例如C或C++时用到过同步,你会知道它用起来有一点诡异。这是因为很多语言它们自己不支持同步。相反,对同步线程,程序必须利用操作系统源语。幸运的是Java通过语言元素实现同步,大多数的与同步相关的复杂性都被消除。 你可以用两种方法同步化代码。两者都包括synchronized关键字的运用,下面分别说明这两种方法。 使用同步方法 Java中同步是简单的,因为所有对象都有它们与之对应的隐式管程。进入某一对象的管程,就是调用被synchronized关键字修饰的方法。当一个线程在一个同步方法内部,所有试图调用该方法

Java多线程学习-----wait()、notify/notifyAll()的使用

匿名 (未验证) 提交于 2019-12-02 21:45:52
多线程的几种状态 新建 就绪 运行 阻塞 死亡 新建: 线程被创建出来 就绪: 具有CPU的执行资格, 但是不具有CPU的执行权 运行: 具有CPU的执行资格, 也具有CPU的执行权 阻塞: 不具有CPU的执行资格, 也不具有CPU的执行权 死亡: 不具有CPU的执行资格, 也不具有CPU的执行权 线程的阻塞状态 上一篇有说过sleep可以使线程处于阻塞状态,今天要说的 wait() 方法也可以使线程处于阻塞状态。首先来看一下这两个方法的区别; 共同点: wait()方法和sleep()方法 都可以使线程处于阻塞状态 都可以设置线程的阻塞时间 不同点: wait() 可以设置时间量,也可以不设置。 sleep() 是要必须要设置休眠的时间 wait() 必须先获得锁,一般配合synchronized 关键字使用,即,一般在synchronized 同步代码块里使用 wait()、notify/notifyAll() 方法;sleep()不一定要获得锁。 sleep() 休眠不会释放锁 wait() 一旦等待就会释放锁,让出cpu的执行权,直到当 notify/notifyAll() 被执行时候,才会被唤醒然后继续往下执行 wait() 阻塞状态的唤醒 当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态。 只有当 notify/notifyAll()