相思(唐·王维)
红豆生南国,春来发几枝?
愿君多采撷,此物最相思。
目录
五,sleep() ,wait() ,join(),yield()的区别
线程安全描述:当多个线程访问一个对象时,如果不用进行额外的同步控制或其他的协调操作,调用这个对象的行为都可以获得正确的结果,我们就说这个对象是线程安全的
一,双亲委派模型(双亲委托)
一个程序的启动从main函开始,appClassLoader加载器就会开始向上委派(查找appClassLoader到顶级加载器BootStrapClassLoader查找缓存) ,当缓存找到就返回,如果在顶级加载器都没有找到就会向下查找(从顶级加载器到发起加载器进行路径查找)。找到就返回,没有找到就返回找不到
优点
1,为了安全性,避免程序员自己编写类替换了Java中的核心类,如:String
2,避免了类的重复加载,因为jvm中区分不同的类,不仅仅根据类名称,相同的.class文件被不同的加载器加载就是二个不同的文件
二,Java中的异常体系
Java中的所有异常都来自顶级父类Throwable。
Throwable下有两个子类Exception和Error。
Error
Error是程序无法处理的错误,一旦出现这个错误,则程序将被迫停止运行。如 oom(栈溢出)
Exception:
Exception不会导致程序停止,又分为两个部分RunTimeException运行时异常与CheckedException检查异常。
RunTimeException常常发生在程序运行过程中,会导致程序当前线程执行失败。如:空指针,下标越界(程序员自定义异常一般继承RunTimeException)
CheckedException常常发生在程序编译过程中,会导致程序编译不通过,如:int类型写为字符串类型
三,Gc如何判断对象可以被回收的
引用计数法(Java中并没有用,python中有使用):
每一个对象都有一个引用计数的属性,新增一个引用计数加1,引用释放时计数减1,当引用计数为0时,就可以回收该对象
优点:效率高
缺点:当A引用B,B引用A时,二个对象计数都为1,当不需要使用A与B,因为引用计数法该对象A与B没有办法被回收
可达性分析法(Java中垃圾回收方法)
从GC Roots开始向下搜索,搜索所有的路径称为引用链,当一个对象到GC Roots没有引用链时,就证明该对象是不看用的,虚拟机(jvm)判断该对象是可以回收的对象
GC Roots对象
1,虚拟机栈中的引用对象
2,方法区中静态属性的引用对象
3,方法区中常量的引用对象
4,本地方法栈中JNI/(一般说是Native方法)引用对象
四,线程的生命周期与状态
线程状态的详细了解https://blog.csdn.net/weixin_47514459/article/details/121684582
线程的生命周期
从线程的创建到线程死亡时的过程称为一个周期。
线程的状态
线程分为五种状态:创建,就绪,运行,阻塞与死亡。
五,sleep() ,wait() ,join(),yield()的区别
线程方法了解https://blog.csdn.net/weixin_47514459/article/details/121385539
锁池
所有需要竞争同步锁的线程都会放在锁池当中,比如当前对象的锁已经被其中一个线程得到,则其他线程需要在这个锁池进行等待,当前面的线程释放同步锁后锁池中的线程去竞争同步锁,当某个线程得到后会进入就绪队列进行等待cpu资源分配。
等待池
当我们调用wait ()方法后,线程会放到等待池当中,等待池的线程是不会去竞争同步锁。只有调用了notify ()或notifyAlI)后等待池的线程才会开始去竞争锁,notify ()是随机从等待池选出一个线程放到锁池,而notifyAllo)是将等待池的所有线程放到锁池当中
相同点:
这四个方法都是线程当中使用的方法
sleep() ,wait()的区别(!!!)
1, sleep是Thread类的静态本地方法,wait则是 Object类的本地方法。
2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。
3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。
4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。
5、sleep一般用于当前线程休眠,或者轮循暂停操作,wait 则多用于多线程之间的通信。
6、sleep会让出CPU执行时间且强制上下文切换,而wait则不一定,wait后可能还是有机会重新竞争到锁继续执行的。
yield ()
执行后线程直接进入就绪状态,马上释放了cpu的执行权,但是依然保留了cpu的执行资格,所以有可能cpu下次进行线程调度还会让这个线程获取到执行权继续执行
join ()
执行后线程进入阻塞状态,例如在线程B中调用线程A的join (),那线程B会进入到阻塞队列,直到线程A结束或中断线程
六,谈谈你对对线程安全的理解
不是线程安全、应该是内存安全,堆是共享内存,可以被所有线程访问
线程安全描述:
当多个线程访问一个对象时,如果不用进行额外的同步控制或其他的协调操作,调用这个对象的行为都可以获得正确的结果,我们就说这个对象是线程安全的
七,Thread与Runable的区别
Thread和Runnable的实质是继承关系,没有可比性。无论使用Runnable还是Thread,都会new Thread(创建一个新线程),然后执行run方法。用法上,如果有复杂的线程操作需求,那就选择继承Thread,如果只是简单的执行一个任务,那就实现runnable.
八,谈谈你对并发,并行,串行的理解
串行
在时间上不可能发生重叠,前一个任务没搞定,下一个任务就只能等着
并行
在时间上是重叠的,两个任务在同一时刻互不千扰的同时执行。
并发
允许两个任务彼此干扰。统一时间点、只有一个任务运行,交替执行(对于cpu来说也是串行执行的)
九,并发的三大特征(作用:保证线程的安全)
原子性
是指在一个操作中cpu不可以在中途暂停然后再调度,即不被中断操作,要不全部执行完成,要不都不执行。
可见性
当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
有序性
虚拟机在进行代码编译时,对于那些改变顺序之后不会对最终结果造成影响的代码,虚拟机不一定会按照我们写的代码的顺序来执行,有可能将他们重排序。实际上,对于有些代码进行重排序之后,虽然对变量的值没有造成影响,但有可能会出现线程安全问题。