3.4 线程等待(join)方法 等待其他线程终止
join方法只是对object提供的wait()做了一层包装而已,wait方法释放了同步锁
等待该线程终止。如果在主线程中调用该方法,会让主线程休眠,让调用该方法的线程子安执行完毕后再恢复执行主线程
(从运行到阻塞状态,等待时间结束后,从阻塞态到就绪态)
class MyThread implements Runnable {
@Override
public void run() {
try {
System.out.println("主线程睡眠前的时间");
Test.printTime();
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName());
System.out.println("睡眠结束的时间");
Test.printTime();
} catch (InterruptedException e) {// TODO Auto-generated catch block
e.printStackTrace()
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException{
MyThread mt = new MyThread();
Thread thread = new Thread(mt,"子线程A");
thread.start();
System.out.println(Thread.currentThread().getName());
thread.join();
System.out.println("代码结束");
}
public static void printTime() {
Date date=new Date();
DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time=format.format(date);
System.out.println(time);
}
}
3.5 线程停止
1.*******************设置标志位停止线程
代码如下:
class MyThread implements Runnable {
private boolean flag = true;
@Override
public void run() {
int i = 1;
while (flag) {
try {
Thread.sleep(1000);
System.out.println("第"+i+"次执行,线程名称为:"+Thread.currentThread().getName());
i++;
} catch (InterruptedException e) {// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
Thread thread1 = new Thread(myThread,"子线程A");
thread1.start();
Thread.sleep(2000);
myThread.setFlag(false);
System.out.println("代码结束");
}
}
2. 调用stop方法强制停止线程,该方法不安全已经被Deprecated----不安全
3.调用Thread类的interrupt()方法
interrupt()方法只是将线程状态置为中断状态而已,它不会中断一个正在运行的线程,此方法只是给线程传递一个中断信号,程序可以根据此信号来判断是否需要终止。
当线程中使用wait,sleep,join导致此线程阻塞,则interrupt()会在线程中抛出InterruptException,并且将线程的中断状态由true置为fslse.
class MyThread implements Runnable {
private boolean flag = true;
@Override
public void run() {
int i = 1;
while (flag) {
try {/**这里阻塞之后,线程被调用了interrupte()方法,清除中断标志,就会抛出一个异常java.lang.InterruptedException*/
Thread.sleep(1000);
boolean bool = Thread.currentThread().isInterrupted();
if (bool) {
System.out.println("非阻塞情况下执行该操作。。。线程状态" + bool);
break;
}
System.out.println("第"+i+"次执行,线程名称为:"+Thread.currentThread().getName());
i++;
} catch (InterruptedException e) {
System.out.println("退出了");
/**
* 这里退出阻塞状态,且中断标志被系统会自动清除,
* 并且重新设置为false,所以此处bool为false
*/
boolean bool = Thread.currentThread().isInterrupted();
System.out.println(bool);
//退出run方法,中断进程
return;
}
}
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
Thread thread1 = new Thread(myThread,"子线程A");
thread1.start();
Thread.sleep(3000);
thread1.interrupt();
System.out.println("代码结束");
}
3.6线程优先级
线程优先级是指优先级越高越有可能先执行,但仅仅是有可能而已
设置优先级的方法
Public final void setPriority(int newPriority)
取得优先级
Public final int getPriority()
MAX_PRIORITY=10;
NORM_PRIORITY=5;普通优先级
MIN_PRIORITY=1;
主线程只是一个普通优先级而已
线程具有继承性:只是继承优先级而已
从A线程启动B线程,则B和A的优先级相同
3.7守护线程
守护线程是一种特殊的线程,又称为陪伴线程,JAVA中一共有两种线程:用户线程与守护线程
Thread类提供isDaemon()区别两种线程:返回flase表示该线程为用户线程;否则为守护线程。典型守护线程就是垃圾回收线程
只要当前JVM进程中存在一个进程没有结束,守护线程就在工作;只有当最后一个用户线程结束时,守护线程才会随着JVM一同停止工作
Thread提供setDaemon()将用户线程设置为守护线程。