题解一:
处理问题:
1、为什么使用了isAlive判断线程状态后,使用interrupt方法为什么还是无法中断线程
—>对策:多次判断再中断
2、同时使用sleep和interrup产生的sleep interrupted问题
—>对策:使用Lock锁
package com.company;
import java.util.Date;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
编写一个程序:用一个线程每隔1秒显示系统日期时间,另一个线程打印一个大数的所有因子,当质数计算完毕后,停止时间的显示
*/
class thread1 implements Runnable {
Lock lock;
public thread1(Lock lock){
this.lock=lock;
}
public void run() {
while(!Thread.interrupted()) {
lock.lock();
Date date1 = new Date();
System.out.println(date1);
try {
if (Thread.currentThread().isInterrupted()) {
break; //虽然主函数使用了interrupt,但是它只是发送一个中断命令,并不会立即终止线程,所以还需要进行判断
} //否则会抛出异常:sleep interrupted
new show(0);
Thread.sleep(1000);//沉睡1秒
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
new show(1);
}
}
}
}
class thread2 implements Runnable{
private long num=0;
Object lock=new Object();
public thread2(long num){
this.num=num;
}
public void run(){
System.out.println("这个大数"+num+"的因子有:");
for(int i=1;i<=num;i++){
if (num%i==0){
System.out.println(i);
}
}
}
}
class show{
static int b=0;
show(){}
show(int b){
this.b=b;
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Scanner in=new Scanner(System.in);
long num=in.nextLong();
final Lock lock =new ReentrantLock(); //定义一个锁
thread1 mythread1=new thread1(lock);
Thread t1=new Thread(mythread1,"显示日期时间的线程");
thread2 mythread2=new thread2(num);
Thread t2=new Thread(mythread2,"打印大数因子的线程");
t1.start();
t2.start();
while(true) { //因为t1和t2加入了主线程,且不知道它们什么时候会结束,需要一直等到主线程捕获到t2结束
if (!t2.isAlive()&&show.b==1) { //只有当lock块进行结束后才能中断,也就是在sleep状态不能使用中断操作
t1.interrupt();
if(t1.isInterrupted())
break;
}
}
}
}
/*
其实在本题中还可以在打印因子的过程结束后使用System.exist(0)直接结束全部线程
*/