1、join线程:
一个线程等待另一个线程完成的方法
class TestJoin extends Thread {
// 有参数构造器,设置名字
public TestJoin(String name) {
super(name);
}
// 重写run方法,定义线程执行体
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName() + " " + i);// 创建启动线程,每个线程执行在这里循环打印10次
}
}
public static void main(String[] args) throws Exception {
// 启动子线程
new TestJoin("新线程").start();
for (int i = 0; i < 10; i++) {
if (5 == i) {
TestJoin jn = new TestJoin("被join的线程");
jn.start();
jn.setPriority(MAX_PRIORITY);// 设置优先级
jn.join();
// jn.sleep(5000); 线程睡眠,5秒后才执行最后打印主线程
}
System.out.println(Thread.currentThread().getName() + "" + i);// 打印主线程
}
}
}
新线程和主线程并发执行,为5时启动被join的线程,该线程不和主线程并发执行,主线程等待该线程执行完毕才可以执行。
2、线程睡眠:sleep
让线程暂停一段时间,进入阻塞状态。
3、线程让步:yield
yield让当前正在执行的线程暂停,不会阻塞线程,只是让线程转入就绪状态。让系统的线程调度器重新调度一次,完全可能yield之后又被调度器重新调度(主要看优先级)。
4、sleep和yield区别:
1、sleep阻塞态,给其他线程机会,不看优先级,yield就绪态。
2、sleep之后,过了阻塞时间才转入就绪态。
3、sleep声明抛出InterruptException异常,yield没有声明任何异常。
4、sleep可移植性好。
5、改变线程优先级
高优先级先执行,线程与创建他的父线程优先级相同,main方法普通优先级。
Thread提供setPriority(int newPriority)和getPriority(),setPriority范围1-10;
静态变量:MAX_PRIORITY :10 MIN_PRIORITY: 1 NORM_PRIORITY:5
6、后台线程(守护线程)
所有前台线程都死亡,后台线程自动死亡。如JVM垃圾回收线程。
Thread.setDaemon(true)设置为后台线程,必须在start之前调用。
public class TestDemon extends Thread {
public void run() {
for (int i = 0; i < 10000; i++) {
System.err.println(getName() + " " + i);
}
}
public static void main(String[] args) {
TestDemon daemon = new TestDemon();
daemon.setDaemon(true);// 设置为后台线程
daemon.start();
for (int i = 0; i < 10; i++) {
System.err.println(Thread.currentThread().getName() + " " + i);
}
// 执行到此,main线程结束,后台线程随之结束
}
}
后台线程无法运行到9999。
7、线程通信
Object类提供了wait()、notify()、notifyAll()三个方法,这三个方法不属于Thread类。三个方法必须由同步监视器对象调用;
1、用synchronized修饰的同步方法,默认实例this就是,可在同步方法直接调用。
2、 用synchronized修饰的同步代码块,是synchronized后括号中的对象。
Wait():让当前线程等待,之前其他线程调用该同步监视器的notify或notifyall唤醒。
Notify():唤醒在同步监视器上等待的线程。
Notifyall():唤醒在同步监视器上等待的所有线程。