import java.util.Scanner;//在main方法中创建并启动两个线程。
//第一个线程循环随机打印100以内的整数,
//直到第二个线程从键盘读取了“Q”命令。class RandomWriter1 implements Runnable { public static boolean loopFlag = true; @Override
public void run() {
while (loopFlag) {
System.out.println((int) (Math.random() * 100)); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }}class StopRandomWriter implements Runnable {
@Override
public void run() {
Scanner scanner = new Scanner(System.in);
while (true) {
String next = scanner.next();
while (next.equalsIgnoreCase("Q")) {
RandomWriter1.loopFlag = false;
}
}
}
}public class homework4 { public static void main(String[] args) { StopRandomWriter srw = new StopRandomWriter();
Thread thread2 = new Thread(srw);
thread2.start(); RandomWriter rw = new RandomWriter();
Thread thread = new Thread(rw);
thread.start(); }
}

解决方案 »

  1.   

    1  volatile
    2  输入Q后获得的字符是否包括回车字符,如果有则不会相等。新手之言~
      

  2.   

    这种写法是可以中止线程的。你main函数中实例化的是  RandomWriter,但是你上面定义的却是 RandomWriter1 
    检查一下两者是否是同一个
    RandomWriter1  类中线程睡眠的时间改长一些建议改为5秒钟一次确保你输入的是大写的Q 且按了回车键
      

  3.   

    关于lz的实现,起始“在一般情况下”是没问题的,但是,非常不推荐这种方式实现线程的信号同步。
    首先,将楼主的代码做一下更改://在main方法中创建并启动两个线程。
    //第一个线程循环随机打印100以内的整数,
    //直到第二个线程从键盘读取了“Q”命令。class RandomWriter1 implements Runnable { public static boolean loopFlag = true; @Override
    public void run() {
    while (loopFlag) {
    System.out.println((int) (Math.random() * 100)); try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    System.out.println("I am ready to stop."); //这句,跳出循环进行输出,判断信号量是否有效
    }}然后在执行,输入Q:46
    59
    Q16I am ready to stop.可以看到,程序输出了“I am ready to stop.”这句,然后你的thread线程会终止。
    至于你的程序为什么不会终止,原因是你没有在输入Q后使thread1线程终止,这么改:class StopRandomWriter implements Runnable {
    @Override
    public void run() {
    Scanner scanner = new Scanner(System.in);
    while (true) {
    String next = scanner.next();
    while (next.equalsIgnoreCase("Q")) {
    RandomWriter1.loopFlag = false;
    return; //这里,跳出方法,使得StopRandomWriter这个线程可以终止
    }
    }
    }
    }然后,输入Q,你的程序就可以正常终止了。
    但是,正如前面所说,这种同步方式,是有非常大的隐患的,因为你的loopFlag不能满足读写操作的happens-before,所以在多个写线程(也就是StopRandomWriter )操作该变量时,会出现脏值问题。对于多个读线程或多个写线程并发操作环境下,会出现死锁问题。推荐进行如下的更改:import java.util.Scanner;
    import java.util.concurrent.atomic.AtomicBoolean;//在main方法中创建并启动两个线程。
    //第一个线程循环随机打印100以内的整数,
    //直到第二个线程从键盘读取了“Q”命令。class RandomWriter1 implements Runnable { public static AtomicBoolean loopFlag = new AtomicBoolean(true); //用满足读写happens-before的AtomicBoolean替代boolean @Override
    public void run() {
    while (loopFlag.get()) { //volidate 读
    System.out.println((int) (Math.random() * 100)); try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    System.out.println("I am ready to stop.");
    }}class StopRandomWriter implements Runnable {
    @Override
    public void run() {
    Scanner scanner = new Scanner(System.in);
    while (true) {
    String next = scanner.next();
    while (next.equalsIgnoreCase("Q")) {
    RandomWriter1.loopFlag.set(false); //CAS写(如果你的写入线程)
    return; //这里,跳出方法,使得StopRandomWriter这个线程可以终止
    }
    }
    }
    }public class homework4 { public static void main(String[] args) { StopRandomWriter srw = new StopRandomWriter();
    Thread thread2 = new Thread(srw);
    thread2.start(); RandomWriter1 rw = new RandomWriter1();
    Thread thread = new Thread(rw);
    thread.start(); }
    }
    这样就可以比较安全的实现你的需求了,修改也是比较小的。