sleep和wait经常被面试官问到,它们的区别如下:
1.sleep是Thread类的静态本地方法,wait则是Object类的本地方法。
2.sleep方法不会释放lock,但wait会释放,而且会加入到等待队列。
sleep就是把cpu的执行资格和执行权释放了出去,不再运行此线程,当定时时间结束再取回cpu资源,参与cpu的调度,获取到cpu资源后就可以继续运行了。而如果sleep是该线程有锁,那么sleep不会释放这个锁,而是带着锁进入冻结状态,也就是说其他需要这个锁的线程根本不可能得到这个锁,也就是说无法执行程序。如果睡眠期间其他线程调用了这个线程的interrupt方法,那么这个线程也会抛出interruptexception异常返回,这点和wait是一样的。
3.sleep方法不依赖与同步器synchronized,但是wait需要依赖synchronized关键字。
4.sleep不需要手动唤醒,wait需要。
5.sleep一般用于当前线程休眠,或则轮询暂停操作,wait则用于多线程之间的通信。
6.sleep会让出cpu执行时间且强制上下文切换,而wait则不一定,wait后可能还有机会重新竞争到锁继续执行的。
执行结果:
22222222
1111
其实不是线程安全,应该是内存安全,堆是共享内存, 可以被所有线程所访问
当一个多线程访问一个对象时,如果不进行额外的同步控制或其他协调操作,调用这个对象的行为都可以获得正确的结果,我们就说这个线程是安全的。
堆是进程和线程共有的空间,分为全局堆和局部堆。全局堆是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程进行初始化的时候分配,运行过程中也可以向系统要额外的堆,但是用完了还要还给操作系统,要不然就是内存泄漏。
在java中,堆是java虚拟机所管理内存中最大的一块,是所有线程共享的一块区域,在虚拟机启动时创建。堆所存在的内存区的唯一目的就是存放对象实例,几乎所有的对象实例和数组都在这里分配内存空间。
网络上有个如下的例子,列举出runable在数据共享上更好用,其实这个推断是不对的,这个例子的代码设计就产生了错误,第一个new了两个对象,第二个new了一个对象,导致产生的错误。