线程的生命周期
线程常见方法
start() 启动当前线程,表面上调用start方法,实际在调用线程里面的run方法。
- run()线程类继承Thread类或者实现Runnable接口的时候,都要重新实现这个run方法,run方法里面是线程要执行的内容。
- currentThread:Thread类中一个静态方法,获取当前正在执行的线程
- setName设置线程的名字
- getName读取线程名字
- join:当一个线程调用了join方法,这个线程就会被执行,它执行结束以后才可以去执行其余的线程。注意:必须先start,再join才有效
- sleep:Thread类中一个静态方法。是一个人为的阻塞方法。
- setDeamon:设置伴随线程。
- stop:停止线程。
设置优先级别
- 同优先级别的线程,采取的策略就是先到先服务,使用时间片策略
- 如果优先级别高,被cpu调度的概率就高
- 级别:1-10级,默认的级别为5
锁(同步监视器)
- 必须是引用数据类型,不能是基本数据类型
- 页可以创建一个专门的同步监视器,没有任何业务含义
- 一般使用共享资源做同步监视器即可
- 在同步代码块中不能改变同步监视器对象的引用。
- 尽量不要String和包装类Integer做同步监视器
- 建议使用final修饰同步监视器
同步代码块的执行过程
- 第一个线程来到同步代码块,发现同步监视器open状态,需要close然后执行其中的代码
- 第一个线程执行过程中,发生了线程切换(阻塞、就绪),第一个线程失去了cpu,但是没有开锁open。
- 第二个线程获取cpu,来到了同步代码块,发现同步监视器close状态,无法执行其中的代码,第二个线程也进入阻塞状态
- 第一个线程再次获取cpu,接着执行后续的代码,同步代码块执行完毕,释放锁open.
- 第二线程也再次获取cpu,来到了同步代码块,发现同步监视器open状态,拿到锁并且上锁,由阻塞状态进入就绪状态,再进入运行状态,重复第一个线程的处理过程(加锁)
强调:同步代码块中发生cpu的切换?能,但后续的被执行线程也无法执行同步代码块(因为锁依旧close)
- 方法中放入synchronized表示锁的是当前实例this
- 方法中放入 static synchronized表示锁的是当前字节码文件。