【问题标题】:Control of running Thread using multiple threading concept of java使用java的多线程概念控制运行线程
【发布时间】:2015-07-30 05:44:27
【问题描述】:

我只想在按下返回键时启动和停止线程。 这里线程停止正常但我无法再次启动该线程请帮助。 还要解释一下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;
    }



}

主类``

    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)

【问题讨论】:

标签: java multithreading volatile


【解决方案1】:

线程是不可重入的,即一旦退出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,原因有很多,但您会发现将来最有用的一个是Runnable在 API 的不同部分(如 Executors API)得到更广泛的支持,使其成为更灵活的选择

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

【讨论】:

    猜你喜欢
    • 2014-02-25
    • 2013-09-07
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多