Java适合多线程实现?

时间:2015-04-27 18:11:12

标签: java multithreading

我对多线程非常陌生 - 我做了几个小时的研究并测试了几种不同的方法。我最近实现了这段代码:

public class resetDataThread implements Runnable {
    VertexHashMap allVertices;
    public resetDataThread(VertexHashMap allVertices){
        this.allVertices = allVertices;
    }            

    @Override
    public void run() {
        for (int i = 0; i < allVertices.data.length; i++)
        {
            if (allVertices.data[i] != null){
                allVertices.data[i].inClosed = false;
                allVertices.data[i].inOpen = false;
            }           
        }        
        System.out.println("Thread Finished!");        
    }    
}

请注意,VertexHashMap是一个存储顶点的自实现哈希映射。

Runnable r = new resetDataThread(allVertices);
Thread t1 = new Thread(r);

我这样称呼方法:

t1.run();

这行代码被多次调用而不创建r或t1的新实例。 我实现这个的原因是我的程序可以在重置存储的布尔变量(allVertices)时获取新数据和输出结果。我的主要目标是我的程序的执行速度,所以我想我可以多线程这部分代码。

所以我的问题是,这是安全的,合适的还是一种好方法?

实施例

...code that changes allVertices variables
t1.run(); //this will run while otherSectionOfProgram and yetAnotherSectionOfProgram is executed
otherSectionOfProgram();
yetAnotherSectionOfProgram();

上面的例子可以多次调用,但allVertices的内容总是相同的(布尔设置除外),所以我只是想确保可以像我一样使用run()方法有 - 因为我想确保我练习好的java /编程。

5 个答案:

答案 0 :(得分:2)

如果您追求的是运行单个后台线程,请调用t1.start()以启动后台线程。

如果您希望通过创建线程获得更高级的功能,请查看Executor Service for java Java Executor Service

值得注意的是,除非allVertices的体积非常大,否则无论如何都不需要花费太多时间来运行run()方法,但它很容易让它看时间它有多大差异。

编辑: 还要确保otherSectionOfProgram();而又是另一个部分的程序();如果您没有创建新的实例,请不要修改allVertices,因为您的后台线程也将对其进行操作。

答案 1 :(得分:0)

t1.run();
     

这行代码被多次调用

在您的主题上调用start(),而不是run()

What's the difference between Thread start() and Runnable run()

答案 2 :(得分:0)

您使用t.run()方法启动创建的主题,t.start() 赢得 启动新主题。

此外,多次调用t仍然赢了每次调用时都会创建一个新线程,您的线程<?php // 1. get session user object $user = (isset($_SESSION['user'])) ? $_SESSION['user'] : null; // 2. set vars if($user) { if(isset($user['first_name'])) { $first_name = $user['first_name']; } if(isset($user['level'])) { $level = $user['level']; } } // 3. set flag (optional) or access $level directly if(isset($level)) { $isAdmin = ($level === "Admin") ? true: false; } // normal user: Hello (name of user), Home, Blog, Write a blog, Logout, // admin logs : Hello (name of user), Home, Blog, Write a blog, Admin, Logout, ?> 无法使用(死)完成一次之后。你需要为每个......井......线程创建新的线程。

答案 3 :(得分:0)

要开始新主题,您应该调用start()方法 为了安全起见,你应该注意互斥,我应该知道程序的逻辑,以便为你提供更多关于正确解决方案的建议,但是如果程序的另一部分可能同时改变它或者你想要它,你可能想要同步allVertices创建线程的多个实例:

@Override
public void run() {
    synchronized(allVertices){
        for (int i = 0; i < allVertices.data.length; i++)
        {
            if (allVertices.data[i] != null){
                allVertices.data[i].inClosed = false;
                allVertices.data[i].inOpen = false;
            }           
        }
    }
    System.out.println("Thread Finished!");        
}  

答案 4 :(得分:0)

好的,首先,调用Thread.run() 会启动新的Thread。它将在调用线程上运行该方法。要实际启动新线程,您必须使用Thread.start()。在您发布的代码中,发生 no 多线程。

其次,行VertexHashMap is a self implemented hash map that stores Vertices.尖叫非线程安全给我。您知道有一个特殊的ConcurrentHashMap版本的HashMap来处理并发(即多线程)使用吗?你的课程基于哪种结构?你有自己的对象线程安全吗?可能会出现线程间可见性问题。

第三,重用线程是一项棘手的工作。只需多次调用run即可创建一个Thread,但多次调用start会引发异常。正如其他一些答案所指出的那样 - 使用ExecutorService是一个很好的选择 - 您可以将其设置为使用您想要的任意数量的线程(并且在负载下具有灵活性),并重复使用它它的线程(而不是重新发明它背后的复杂机制)。

最后 - 您可能想要考虑对象的可见性。在您的情况下,VertexHashMapdefault可见性。这意味着其他类可以直接查看和使用它。例如,如果您正在清理或重新填充,则可能会出现问题。然后用户获得一个半就绪对象,其方法可能很容易失败。 Java只有一个Future接口 - 它是一个用于多线程的接口,它承诺&#34;返回一个准备好的对象。它是Swings SwingWorker和Androids AsyncTask的基础 - 在后台线程中执行任务的对象,然后将准备好的结果返回到前台以供进一步使用。