使用java的多线程概念控制运行Thread

时间:2015-07-30 05:44:28

标签: java multithreading volatile

我只想在按下返回键时启动并停止线程。 这里线程停止正常,但我不能再次启动该线程请帮助。 还解释了我使用volatile关键字。这对我来说是有帮助的。

public class Sync extends Thread{

    public boolean meth= true;
    public void run(){
        while(meth){
            System.out.println("hello");
            try {

                Thread.sleep(1000);
            } catch (InterruptedException ex) {

            }
           }
    }
    public void shutdown(){
       meth=false;
    }
    public void startup(){
        meth=true;
    }



}

MAIN CLASS``

    package com.Sync;

import java.util.Scanner;


public class SyncMain {
    public static void main(String[] arg) throws InterruptedException{
        Sync hi= new Sync();
        hi.start();
        System.out.println("press enter to stop");

        Scanner d= new Scanner(System.in);

        d.nextLine();
        hi.shutdown();
        System.out.println("press enter to start");
        d.nextLine();
        hi.startup();



    }

}

输出

   run:
press enter to stop
hello
hello
hello
hello

press enter to start

BUILD SUCCESSFUL (total time: 6 seconds)

1 个答案:

答案 0 :(得分:2)

线程不是可重入的,也就是说,一旦它们退出run方法,它们就无法重新启动,您需要创建一个新实例。

一个解决方案是创建Sync的新实例并启动它,但基于您的代码可能更好的解决方案是使用wait锁来“暂停”线程和允许它恢复,例如......

public static class Sync implements Runnable {

    private AtomicBoolean keepRunning = new AtomicBoolean(true);
    private AtomicBoolean pause = new AtomicBoolean(false);

    private ReentrantLock lckPause = new ReentrantLock();
    private Condition conPause = lckPause.newCondition();

    public void run() {
        while (keepRunning.get() && !Thread.currentThread().isInterrupted()) {
            while (pause.get() && !Thread.currentThread().isInterrupted()) {
                lckPause.lock();
                try {
                    System.out.println("Paused");
                    conPause.await();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                } finally {
                    lckPause.unlock();
                }
            }
            if (!Thread.currentThread().isInterrupted()) {
                System.out.println("hello");
                try {

                    Thread.sleep(1000);
                } catch (InterruptedException ex) {

                }
            }
        }
    }

    public void setPaused(boolean paused) {
        if (pause.get() != paused) {
            pause.set(paused);
            if (!paused) {
                lckPause.lock();
                try {
                    conPause.signal();
                } finally {
                    lckPause.unlock();
                }
            }
        }
    }

    public void terminate() {
        keepRunning.set(false);
        setPaused(false);
    }

}

这基本上设置了两个循环,一个用于保持线程运行直到它“终止”,一个用于捕获“暂停”条件......

然后你可以做一些像......

public static void main(String[] args) {
    Sync hi = new Sync();
    Thread t = new Thread(hi);
    t.start();

    Scanner d = new Scanner(System.in);
    System.out.println("press enter to pause");
    d.nextLine();
    hi.setPaused(true);
    System.out.println("press enter to resume");
    d.nextLine();
    hi.setPaused(false);
    System.out.println("press enter to terminate");
    d.nextLine();
    hi.terminate();

    try {
        t.join();
    } catch (InterruptedException ex) {
        ex.printStackTrace();
    }

    System.out.println("Has terminated");
}

简单地运行它......

您应该注意到,通常不建议直接从Thread扩展,并且通常鼓励使用单独的Runnable,原因有很多,但您将来发现最有用的原因是API的不同部分(例如Runnable API)更广泛地支持Executors,使其成为更加灵活的选项

查看Concurrency Trail了解更多详情,尤其是Lock Objects