Java

2 minute read

  一直不太清楚在JDK中包含的那些原生有关并发的基础方法的作用,由于平时没有实际用到过,所以着重研究了下这些方法的异同点。
wait方法
  当一个线程调用了某对象的wait方法时,该线程会被阻塞挂起,直到发生下面几件事情之一才返回:
  1. 其它线程调用了该共享对象的notify或者notifyAll方法。
  2. 其它线程调用了该线程的interrupt方法,该线程抛出InterruptedException异常返回。
  如果线程调用wait方法时,没有事先获取该对象的监视器锁,则线程调用wait方法时会抛出IllegalMonitorStateException。
  当前线程调用共享变量的wait的方法后,只会释放当前共享变量的锁,如果当前线程还持有其它共享变量的锁,则这些锁是不会被释放。
PS:wait(long timeout)方法
  相比于wait函数,多了一个超时参数,不同之处在于,如果一个线程调用共享对象的wait方法挂起后,没有在指定的timeout内被其它的线程调用该共享变量的notify或notifyAll方法唤醒,该函数会因为超时而返回。
notify方法
  一个线程调用共享对象的notify方法后,会唤醒一个在该共享变量调用wait方法被挂起的线程,一个共享变量上可能会有多个线程被挂起等待,具体唤醒哪个线程是随机的。 被唤醒的线程不能马上从wait方法返回并继续执行,它必须获取到锁后才能继续执行,就是说被唤醒的线程不一定会获取到该共享对象的监视器锁,因为该线程需要和其它线程一起竞争该锁,只有该线程竞争到该变量的锁后,才能继续执行。
  只有当前线程获取到共享对象的锁后,才可以调用notify方法,否则会抛出IllegalMonitorStateException。
PS:notifyAll方法
  不同于notify函方法随机唤醒阻塞在该共享变量的一个线程,notifyAll方法会唤醒所有在该共享变量由于调用wait方法而被挂起的线程。
join方法
  join方法是Thread类直接提供的,join是无参且返回值为void的方法。线程A调用线程B的join方法后会阻塞,当其它线程调用了线程A的interrupt方法中断线程A时,线程A抛出InterruptException异常而返回。
sleep方法
  sleep方法是Thread类中的静态方法,当一个执行中的线程调用了Thread类的sleep方法后,调用线程会暂时放弃CPU,但不会放弃线程持有的监视器资源,比如锁。 指定的时间到后,函数会正常返回,此时线程处于就绪状态,参与CPU的调度,获取到CPU资源后就可以继续运行。如果在睡眠期间其它线程调用了该线程的interrupt方法中断了该线程,则该线程会在调用sleep的地方抛出InterruptedException异常而返回。
yield方法(很少使用)
  Thread类中有一个静态的yield方法,当一个线程调用yield方法时,实际上是暗示当前线程放弃自己的CPU,但是线程调度器可以无条件忽略这个请求。仍有可能调度到当前线程执行。
  sleep和yield方法的区别在于,当线程调用sleep方法时,调用线程会被阻塞挂起指定的时间,在这期间线程调度器不会去调度该线程,而调用yield方法,线程只是让出自己剩余的时间片,并没有阻塞挂起,而是处于就绪状态,线程调度器下次调度时仍有可能调度到该线程。
interrupt方法
  线程中断是线程间的协作模式,通过设置线程的中断标志并不能直接终止该线程的执行,而是被中断的线程自行处理。
  interrupt方法,中断线程,线程A运行时,线程B可以调用线程A的interrupt方法设置A的中断标志为true并立即返回。如果线程A调用了wait、join、sleep方法而被阻塞挂起,这时线程B调用线程A的interrupt方法,线程A会在调用这些方法的地方抛出InterruptedException异常返回。
  isInterrupted方法,检测当前线程是否中断。
  interrupted方法,检测当前线程是否中断,与isInterrupted不同的是,如果发现当前线程被中断,会清除中断标志,并且该方法是静态方法,可以通过Thread类直接调用。
Object类中的方法

1,构造函数 2,hashcode equals https://www.cnblogs.com/skywang12345/p/3324958.html 3,wait notify notifyAll https://www.cnblogs.com/loren-Yang/p/7538482.html 4,clone 5,finalize 6,toString getClass

参考
《并发编程之美》

什么场景会使用avl树? windows对进程地址空间的管理用到了AVL https://marian5211.github.io/2018/03/09/B%E6%A0%91%E3%80%81B-%E6%A0%91%E3%80%81AVL%E6%A0%91%E3%80%81Trie%E6%A0%91%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF/ 由于维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。 当然,如果应用场景中对插入删除不频繁,只是对查找要求较高,那么AVL还是较优于红黑树。

Java中一般用什么类型表示价格 java.math.BigDecimal 在数据库中不使用BigDecimal,而是使用decimal

byte[]和string之间的转换 https://www.jianshu.com/p/17e771cb34aa

string类不可变的原因是什么? https://juejin.cn/post/6844903501630275597 线程安全 底层其实是char[]数组被final修饰,可用通过反射强行改变

java线程通信方式? https://redspider.gitbook.io/concurrent/di-yi-pian-ji-chu-pian/5 1、锁、synchronized 2、等待、通知 wait/notify 3、信号量 java自己实现了一种基于volatile关键字的自己实现的信号量通信 4、管道 JDK提供了PipedWriter、 PipedReader、 PipedOutputStream、 PipedInputStream 其中,前面两个是基于字符的,后面两个是基于字节流的。

java模拟堆溢出、栈溢出、元数据溢出、直接内存溢出? 栈空间不足时,需要分下面两种情况处理: 线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError 虚拟机在扩展栈深度时无法申请到足够的内存空间,将抛出OutOfMemberError https://blog.csdn.net/u011983531/article/details/63250882 class StackOutOfMemory { int a = 0; public void df() { a ++; df(); }

java中的异常体系是什么? https://www.cnblogs.com/lulipro/p/7504267.html Throwable类是Error类和Exception类的父类 Error类代表jvm本身的错误,不能被捕获 Exception类代表程序运行时各种不期望发生的事件,可以被Java异常处理机制捕获 Exception又可以分为IOException和RuntimeException,RuntimeException包括null指针异常、除0异常等

同时异常又可以分为unchecked exception和checked exception unchecked exception包括Error和RuntimeException checked exception包括除了Error 和 RuntimeException的其它异常

wait方法在synchronized代码块里面为什么需要用while循环包裹? https://blog.csdn.net/u013256816/article/details/106654315 用if判断的话,唤醒后线程会从wait之后的代码开始运行,但是不会重新判断if条件,直接继续运行if代码块之后的代码, 而如果使用while的话,也会从wait之后的代码运行,但是唤醒后会重新判断循环条件,如果不成立再执行while代码块之后的代码块,成立的话继续wait。

notify和notifyAll的区别是什么?为什么notify可能会产生死锁? http://www.zzcblogs.top/2018/03/15/java-notify%E5%92%8CnotifyAll%E5%8C%BA%E5%88%AB/

Updated:

Leave a comment