多线程(二)
线程的优先级
是操作系统中用于指定线程执行顺序的一个机制,它允许用户或程序为线程设置一个优先级值,这个值决定了线程在多任务环境中获得CPU时间的可能性。线程优先级越高,线程获得CPU时间片的概率就越大,但这并不意味着优先级高的线程一定会先于优先级低的线程执行。在Java中,线程的优先级可以通过setPriority(int newPriority)
方法设置,其中优先级分为1~10共10个等级,所有线程的默认优先级为5。如果尝试设置低于1或高于10的优先级,会抛出java.lang.IllegalArgumentException
异常。
最高优先级:thread.setPriority(Thread.MAX_PRIORITY);
最低优先级:thread.setPriority(Thread.MIN_PRIORITY);
默认优先级:thread.setPriority(Thread.NORM_PRIORITY);
给线程自定义名称
- 自己写getThreadName/setThreadName
- 调用父类的一个参数的构造方法和getName
- Thread.currentThread().getName()
让线程休眠 sleep
编写一个抽取学员回答问题的程序,要求倒数三秒后输出被抽中的学员姓名
i. 采用数组存储6个学员姓名 String[]
ii. 生成0-5之间的随机数,确定被抽中的学员 start,end
iii. 在屏幕每隔一秒,依次输出3,2,1,然后输出学员姓名
import java.util.Random;
public class Test01 {
public static void main(String[] args) throws InterruptedException {
String[] names = {"胡歌","彭于晏","吴彦祖","薛之谦","刘宪华","刘德华"};
Random ran = new Random();
int index = ran.nextInt(names.length);
for (int i = 3; i >= 1;i--) {
System.out.println(i);
Thread.sleep(1000);
}
System.out.println(names[index]);
}
}
线程的礼让 yield
正确理解线程的礼让,暂停当前正在执行的线程对象,并执行其他线程。
练习:创建两个线程A,B,分别各打印100次,从1开始每次增加1,其中B一个线程,每打印一次,就yield一次,观察实验结果
class A extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("A:" + i);
}
}
}
class B extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("B:" + i);
//礼让:让当前线程退出CPU资源,该线程马上进入到就绪状态
Thread.yield();
}
}
}
public class Test01 {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.start();
b.start();
}
}
线程的合并 join
g) 主线程和子线程同时运行,满足一定条件后,让子线程先运行至结束
h) 练习:主线程和子线程各打印200次,从1开始每次增加1,当主线程打印到10之后,让子线程先打印完再打印主线程
class MyThread extends Thread{
@Override
public void run() {
for(int i = 1;i<=200;i++){
System.out.println("子线程:"+i);
}
}
}
public class Test01 {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
for(int i = 1;i<=200;i++){
System.out.println("主线程:"+i);
if(i==10){
t.join();//合并:让t线程加入到当前线程
}
}
}
}
线程的中断 Interrupt
thread.interrupt();//改变线程中断值
Thread.currentThread().isInterrupted()//取反
class MyThread extends Thread{
@Override
public void run() {
//Thread.currentThread().isInterrupted() - 判断线程存活状态(false-未销毁 true-销毁)
while(!Thread.currentThread().isInterrupted()){
System.out.println("111");
System.out.println("222");
System.out.println("333");
System.out.println("444");
}
}
}
public class Test01 {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
Thread.sleep(3000);
//关闭线程
t.interrupt();//改变线程存活状态
}
}
守护线程
所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。用户线程和守护线程两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。
class MyThread extends Thread{
@Override
public void run() {
while(true){
System.out.println("后台线程默默守护着前台线程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class A{
public void method(){}
}
class B extends A{
//重写的方法,父类没有抛异常,子类就不能抛
@Override
public void method() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Test01 {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.setDaemon(true);//将当前线程设置为守护线程
t.start();
for (int i = 1; i <= 5; i++) {
System.out.println("主线程:" + i);
Thread.sleep(1000);
}
}
}