我对多线程非常陌生 - 我做了几个小时的研究并测试了几种不同的方法。我最近实现了这段代码:
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 /编程。
答案 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
是一个很好的选择 - 您可以将其设置为使用您想要的任意数量的线程(并且在负载下具有灵活性),并重复使用它它的线程(而不是重新发明它背后的复杂机制)。
最后 - 您可能想要考虑对象的可见性。在您的情况下,VertexHashMap
为default
可见性。这意味着其他类可以直接查看和使用它。例如,如果您正在清理或重新填充,则可能会出现问题。然后用户获得一个半就绪对象,其方法可能很容易失败。 Java只有一个Future
接口 - 它是一个用于多线程的接口,它承诺&#34;返回一个准备好的对象。它是Swings SwingWorker
和Androids AsyncTask
的基础 - 在后台线程中执行任务的对象,然后将准备好的结果返回到前台以供进一步使用。