java基础(二)
1.线程生命周期
- 新建状态
刚new出来的线程对象。
- 就绪状态
调用start方法,就绪状态的线程又叫可运行状态,表示当前线程具有抢夺CPU时间片的权利,CPU时间片就是执行权。当一个线程抢夺到CPU时间片之后,就开始执行run方法,run方法的开始执行标志着线程进入运行状态。
- 阻塞状态
运行状态时,遇到阻塞事件,当一个线程遇到阻塞事件,例如接收用户键盘输入,或者sleep方法等,此时线程会进入阻塞状态,阻塞状态的线程会放弃之前占有的CPU时间片。之后的时间片没了,需要再次回到就绪状态,重新抢夺CPU时间片,称阻塞解除。
- 运行状态
run方法的开始执行标志着这个线程进入运行状态,当之前占有的CPU时间片用完了之后,会重新回到就绪状态抢夺CPU时间片,当再次抢到CPU时间之后,会重新进入run方法,接着上一次的代码继续往下执行。使用JVM的yield方法调度,回到就绪状态,重新对CPU进行抢夺。
- 死亡状态
当run结束,线程结束进入死亡状态。
2.获取当前线程对象
Thread t = Thread.currentThread();
返回值 t 就是当前线程
3.获取线程对象的名字
String name = 线程对象.getName();
4.修改线程对象的名字
线程对象.setName(“线程名字”);
5.获取线程对象的名字
线程对象.getName();
6.线程的sleep方法
1.静态方法 :Thread.sleep(1000);参数时毫秒
2.作用:让当前线程进入休眠,进入“阻塞状态”,放弃占有CPU时间片,让给其它线程使用。根对象无关。
7.终止线程的睡眠
run()当中的异常不能throws,只能try-catch,原因是run()方法在父类中没有抛出任何异常,子类不能比父类抛出更多的异常。
某线程对象.interrupt(); //终断某线程对象的睡眠(这种终断睡眠的方式依靠了java的异常处理机制)。
8.强行终止线程的执行
某线程对象.stop(); //已过时(不建议使用。)
缺点:容易丢失数据,因为这种方式是直接将线程杀死了,容易造成线程中没有保存的数据丢失。
9.合理地终止一个线程的执行
在重写的run方法里面定义一个布尔类型的标记变量用来控制是否让当前线程睡眠?如果变量为false,将通过return来结束当前方法,并且在结束之前可以对数据进行保存,从而达到合理地终止一个线程的执行。
10.线程的调度
- 常见的线程调度模型:
- 抢占式调度模型:
哪个线程的优先级比较高,抢到的CPU时间片的概率就高一些/多一些。java采用的就是抢占式调度模型。
- 均分式调度模型:
平均分配CPU时间片。每个线程占有的CPU时间片时间长度一样。
平均分配,一切平等。
有一些编程语言,线程调度模型采用的是这种方式。
-
java中提供了哪些方法是和线程调度有关系的呢?
-
实例方法
void setPriority(int newPriority) 设置线程的优先级
int getPriority() 获取线程优先级
最低优先级1
默认优先级5
最高优先级10
优先级比较高的获取CPU时间片可能会多一些。(但也不完全是,大概率是多的)
- 静态方法
static void yield() 让位方法
暂停当前正在执行的线程对象,并执行其他线程
yield()方法不是阻塞方法。让当前线程让位,让给其它线程使用。
yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”。
再回到就绪状态之后,有可能还会抢到。
- 实例方法
某线程对象.join(); //当前线程进入阻塞,直到某线程对象执行完之后,当前线程才可以继续执行。称为“合并线程”。
11.多线程并发,数据的安全性问题
什么时候数据在多线程并发的环境下会存在安全问题?
- 多线程并发。
- 有共享数据。
- 共享数据存在修改行为。
12.解决线程安全问题?
-
线程同步机制:就是线程排队执行,不要并发,并发虽然效率高,但是数据不安全。
-
异步编程模型:就是线程之间没有等待关系,实行并发处理,效率较高,数据不安全。
-
同步编程模型:就是线程之间存在等待(排队)关系,效率较低,数据安全。