一、线程的等待和唤醒机制
1、 前提:两个线程公用一把锁,此时可以调用该锁的wait 和notify方法,实现等待唤醒机制。
2、 IllegalMonitorStateException异常原因及解决办法
如果当前线程不是此对象锁的所有者,却调用该对象的wati ,notify方法,该对象抛出此异常。例如:
synchronized(Student.class){
Object.class.notify();
}
注意:必须有线程现在使用着Object.class
3、 sleep和wait的区别
wait:是object类的方法,不需要传递参数,释放锁资源
sleep:是Thread 类的方法,需要传递参数,不释放锁资源
上篇最后,该代码还可以这样改
package cn.itcast.thread;
class Student {
public String name;
public int age;
public boolean flag = false;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
class SetThread extends Thread {
private Student stu;
public SetThread(Student stu) {
this.stu = stu;
}
@Override
public void run() {
int i = 0;
while (true) {
synchronized (stu) {
if (stu.flag) {
try {
stu.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (i % 2 == 0) {
stu.name = "张三";
stu.age = 13;
}else{
stu.name = "李四";
stu.age = 14;
}
i++;
stu.flag=true;
stu.notify();
}
}
}
}
class GetThread extends Thread{
private Student stu;
public GetThread(Student stu){
this.stu =stu;
}
@Override
public void run() {
while(true){
synchronized (stu) {
if(!stu.flag){
try {
stu.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(stu);
stu.flag=false;
stu.notify();
}
}
}
}
public class Test {
public static void main(String[] args) {
// 创建共享数据
Student stu = new Student();
// 创建两个线程,并且让这两个线程同时操作这个共享数据
GetThread get = new GetThread(stu);
SetThread set = new SetThread(stu);
get.start();
set.start();
}
}
二、线程的优先级
1、 线程的优先级别
线程默认优先级是5。范围是1-10
Thread.MAX_PRIORITY //10
Thread.MIN_PRIORITY //1
Thread.NORM_PRIORITY //5
2、 方法
public final intgetPriority():获取线程优先级
public finalvoid setPriority(int newPriority):更改线程的优先级
3、 注意
优先级可以在一定程度上,让线程获较多的执行机会。
三、暂停线程
1、概述
暂停当前正在执行的线程,让其他线程执行
2、成员方法
public static void yield():暂停当前正在执行的线程对象,并执行其他线程。
3、注意
是为了让线程更和谐一些的运行,但是你不要依赖这个方法保证,如果要真正的实现数据依次输出,请使用等待唤醒机制
四、加入线程
1、概念
如果调用一个线程的join方法,那么其他线程必须等待该线程执行完毕后才能执行 ,注意事项:线程必须先启动
2、成员方法
public final void join():等待该线程终止
线程启动后调用该方法
五、守护线程
1、成员方法
public final void setDaemon(boolean on):设置线程为守护线程,一旦前台(主线程),结束,守护线程就结束了
2、注意
main方法就本身是一个线程,我们在main方法里创建线程,并且设置线程为守护线程后,main方法结束后,守护线程就自动结束了