创建一个线程Thread时,JVM将分配一大块内存到专为线程保留的特殊区域上,用于提供运行任务时所需的一切,包括:
- 程序计数器,指明要执行的下一个JVM字节码指令
- 用于支持Java代码执行的栈,包含有关线程已到达当时执行位置所调用方法的信息。它也包含每个正在执行的方法的所有局部变量
- 第二个则用于native code执行的栈
- 线程本地变量的存储区域
- 用于控制线程的状态管理变量
每当调用一个方法时,当前程序计数器被推到该线程的栈上,然后栈指针向下移动以足够来创建一个栈帧,其栈帧里存储该方法的所有局部变量,参数和返回值。所有基本类型变量都直接在栈上,虽然方法中创建对象的任何引用都位于栈帧中,但对象本身存于堆中。
实现Runnable接口比继承Thread的优势
- 适合多个相同的代码去处理同一个资源
- 可以避免java单继承的限制
- 增加程序的健壮性,代码可被多个线程共享,代码和数据独立
方法介绍
- join() 线程加入进来,要等待该线程执行完在继续执行join之后的代码
- yield() 暂停当前正在执行的线程,并执行其他线程,大多数情况下yield()方法会进入就绪状态,重新争抢cpu
- sleep() 在指定的时间内让当前正在执行的线程休眠
- getState() 获取线程状态
- wait() Object的wait()方法、notify()、notifyAll()方法必须要与synchronized(obj)一起使用,只能针对已经获取到obj锁的情况,否则会抛出”java.lang.IllegalMonitorStateException“异常
sleep和wait的区别
- sleep()是Thread的方法,wait()是Object的方法
- sleep()和wait()虽然都释放CPU,但是如果线程持有对象锁资源的话,sleep()不释放锁资源,wait()释放锁资源,
- sleep()需要捕获异常,wait()不需要
- sleep()可以在任意位置使用,wait()必须要在synchronized同步块内使用
Runnable和Callable接口的区别
Runnable中的run()方法返回值为void,Callable中的call方法有返回值且可以抛出异常,可以和Future、FutureTask配合获取异步执行的结果。
自旋锁执行时间短、线程数少的时候使用(由于占用CPU) -----> Atomic和lock都是使用的自旋锁
本文暂时没有评论,来添加一个吧(●'◡'●)