Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中线程的正确方法_Java_Multithreading - Fatal编程技术网

Java中线程的正确方法

Java中线程的正确方法,java,multithreading,Java,Multithreading,我开始学习Java中的线程,现在我有点困惑。 我希望这是一个合适的地方。 我做了一个测试的小程序: public class GetInfo implements Runnable { //private static boolean stopPointerInfo = false; private static Thread tn; public static void StartPointerInfo() { //stopPointerI

我开始学习Java中的线程,现在我有点困惑。 我希望这是一个合适的地方。 我做了一个测试的小程序:

public class GetInfo implements Runnable { 
    //private static boolean stopPointerInfo = false;   
    private static  Thread tn; 

    public static void StartPointerInfo() {
        //stopPointerInfo = false;
        tn = new Thread(new GetInfo());
        tn.start();
        System.out.println("After start1");
    }

    public static void StopPointerInfo() {
        //stopPointerInfo = true;
        tn.interrupt();
    }

    @Override
    public void run() {
        //  while (stopPointerInfo == false) {

        while (! tn.isInterrupted() ) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                tn.interrupt(); 
            }
            .
            .
            doSomething
        }
    }
}
因为
run()
方法必须知道哪个线程被中断,所以我必须使用线程
tn
的全局定义

我应该像以前那样使用
interrupt()
方法,还是像注释中那样使用布尔变量

使用这种方法,我不能使用
中断
,我必须使用布尔版本,因为
Runnable r
不知道这里的线程

public class GetInfo {
    private static boolean stopPointerInfo = false;

    public static void StartPointerInfo() {
        stopPointerInfo = false;
        getPointerInfo();
    }

    public static void StopPointerInfo() {
        stopPointerInfo = true;
    }

    public static void getPointerInfo() {
        Runnable r = new Runnable() { 

            @Override               
            public void run() {
            while (stopPointerInfo == false) {

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) { }
                    .
                    .
                    doSomething
                }
            }   
        };
        new Thread(r).start();  
    }
}

布尔标志解决方案是脆弱的,因为它不能保证更新在不同线程之间可见。要解决此问题,可以将其声明为volatile,但如果设置布尔标志,则不会像在第一个版本中那样中断
sleep
调用。因此,首选使用中断

我认为没有理由将
线程tn
声明为静态。您可以使用:

public class GetInfo implements Runnable { 
    private final Thread tn; 

    private GetInfo() {
        this.tn = new Thread(this);
        this.tn.start();
    }

    public static GetInfo StartPointerInfo() {
        GetInfo info = new GetInfo();
        System.out.println("After start1");
        return info;
    }

    public void StopPointerInfo() {
        tn.interrupt();
    }
    ...
}
然后像这样使用它:

GetInfo infoWorker = GetInfo.StartPointerInfo();
...
infoWorker.StopPointerInfo();
    Thread.currentThread().isInterrupted();

您不需要使用
静态线程

run()
方法中,需要测试当前线程是否已中断。您不需要访问
tn
。您可以这样做:

GetInfo infoWorker = GetInfo.StartPointerInfo();
...
infoWorker.StopPointerInfo();
    Thread.currentThread().isInterrupted();

(请注意,这两个的行为是不同的。一个清除中断标志,另一个不清除。)

或者,您可以将
static
字段更改为实例字段,并使所有
GetInfo
方法成为实例方法。这意味着您可以实例化
GetInfo
的多个实例,每个实例都创建自己的
线程
,并将引用保存在实例字段中


还有两点:

  • 创建和处理线程的方式效率很低。(启动一个线程是昂贵的。)更好的方法是重新构造代码,以便它可以使用一个线程

  • 调用方法
    StartPointerInfo
    StopPointerInfo
    是不好的风格。Java方法名称应始终以小写字母开头