- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这个问题在这里已经有了答案:
What is the difference between Thread.start() and Thread.run()?
(9 个回答)
6年前关闭。
我有一个 General 类,它具有静态方法和静态变量,具有 Hibernate 配置设置和在访问数据库后返回 List 的方法。我正在研究 JavaFx,最近我学会了更好地使用 Task 进行耗时的操作,比如点击 db 以获得一长串数据等。
所以,在我的例子中,我创建了一个 Task 对象,在匿名内部类中编写了代码,其中包含了为 LOGIN 凭据访问数据库的代码。 Task 必须返回 List 的一个实例。
我在静态方法中初始化了一个 Thread 对象,在其构造函数中传递了 Task 的对象,将守护进程设置为 true 并启动了 Thread。但是我在运行应用程序后收到 NullPointerException ..
private static SessionFactory sessionFactory = null;
private static Session session = null;
private static final Transaction transaction = null;
private static final Configuration configuration = null;
private static List list;
public static List getSelectList(final String query)
{
//list = null;
System.err.println("Inside getSelectList");
try{
final Task <List> task= new Task <List> ()
{
@Override
public List call()
{
try
{
System.err.println("Inside call");
session.beginTransaction();
list = session.createQuery(query).list();
System.err.println(list);
session.getTransaction().commit();
return list;
}
catch (Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();
}
System.err.println("Outta try block");
return null;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
System.err.println("Inside handle");
list = task.getValue();
/* for (Iterator it = list.iterator();it.hasNext(); )
{
System.err.println("Inside Set on succeeded");
//System.err.println( ((Login)it.next()).getUsername());
} */
}
});
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
//list=task.getValue();
}
catch (Exception e) {e.printStackTrace();}
return list;
}
/*Thread th = new Thread(task);
th.setDaemon(true);
th.start();*/
task.run();
try
{
session.beginTransaction();
//List locallist = session.createSQLQuery(query).list();
list = session.createSQLQuery(query).list();
session.getTransaction().commit();
return list ;
}
catch (Exception e){
session.getTransaction().rollback();
最佳答案
发生了什么
创建 Thread
完成您的任务,然后调用 start()
在线程上导致task.run()
在您创建的线程中异步执行。
只需调用task.run()
执行 run()
当前线程中的方法。
线程中的代码的行为是不确定的。换句话说,您无法仅从代码中预测结果将是什么。问题是您正在访问共享 list
来自两个不同线程的实例,无法控制访问顺序。这是发生的事情:list
最初是 null
.
您调用getSelectList()
.
在 getSelectList()
:
list
的值到任务完成时的查询结果。 (这将发生在 FX 应用程序线程上。)list
的值getSelectList()
之前完成。达到其
return
陈述。
getSelectList()
达到其
return
任务完成之前的语句(以及在调用任务的
onSucceeded
处理程序之前),
getSelectList()
将返回
list
的值在任务更新它之前,即它将返回
null
.这几乎肯定更有可能发生(因为任务正在访问数据库,这很慢),我希望这就是你得到空指针异常的原因。
onSucceeded
的调用
getSelectList()
之前的处理程序达到其
return
声明,然后由时间
getSelectList()
到达
return
声明,
list
将被更新并返回任务设置的值。这是极不可能的,即使发生了,仍然不能保证您获得
list
的“实时”值。 (由于 Java 语言规范中关于线程和内存之间关系的一些复杂性)。
getSelectList()
来自 FX 应用程序线程,那么您是
保证它将返回
null
, 因为
onSucceeded
在
getSelectList()
之前不可能调用处理程序完成(因为这两个方法调用都在同一个线程上运行 - FX 应用程序线程)。
list
),除非您有适当的同步。同步自己很困难,您通常应该使用高级 API 来为您管理。
Task
API 就是为此而设计的(连同通用的
java.util.concurrent
API)。
static
因为这通常很可怕):
public List getSelectList(String query) throws Exception {
Session session = sessionFactory.createSession();
try {
session.beginTransaction();
List list = session.createQuery(query).list();
session.getTransaction().commit();
return list ;
} catch (Exception e) {
Transaction tx = session.getTransaction();
if (tx != null) {
tx.rollback();
}
throw e ;
}
}
DAO myDAO = ... ;
Task<List> task = new Task<List>() {
@Override
public void call() throws Exception {
return myDAO.getSelectList(...);
}
});
task.setOnSucceeded(event -> {
List list = task.getValue();
// use list to update UI...
});
task.setOnFailed(event -> {
Exception exc = task.getException();
// handle exception...
});
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
public void getSelectList(String query,
Consumer<List> succeededHandler,
Consumer<Exception> errorHandler) {
FutureTask<List> futureTask = new FutureTask<>(() -> {
Session session = sessionFactory.getSession();
try {
session.beginTransaction();
List list = session.createQuery(query).list();
session.getTransaction().commit();
return list ;
} catch (Exception e) {
Transaction tx = session.getTransaction();
if (tx != null) {
tx.rollback();
}
throw e ;
}
});
Thread thread = new Thread(futureTask);
thread.setDaemon(true);
thread.start();
try {
List list = futureTask.get();
succeededHandler.accept(list);
} catch (Exception e) {
errorHandler.accept(e);
}
}
DAO myDAO = ... ;
String query = ... ;
myDAO.getSelectList(query,
list -> Platform.runLater(() -> {
// update UI with list ...
}),
exc -> Platform.runLater(() -> {
// handle exception...
})
);
List
, 而不是Executor
而不是自己管理线程创建。 关于java - 无法在静态方法中将 JavaFx 任务委托(delegate)给新线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29521470/
我有一个加载 View 的 View ,需要将 View 推送到主导航 Controller 。 我已经为每个 View 设置了一个委托(delegate),并且基本上使我的调用沿着“链”返回到主导航
我通过 NSURLConnction 从服务器获取数据,并希望从获取的数组中填充表格 View 。数据出现在 NSURLConnection 委托(delegate)方法的日志中,但我意识到 numb
我已经将我用作标题 View 的 View 子类化,它里面有一些按钮委托(delegate),它工作得很好。 但是,我在 viewController 上方展示了一个 modalViewControl
我希望这听起来像是一个显而易见的问题,但是委托(delegate)返回类型是否也必须与其委托(delegate)的方法的返回类型相匹配? EG,像这样: public static void Save
我想使用 Kotlin 委托(delegate),但我不想在委托(delegate)人之外创建委托(delegate)。委托(delegate)的所有示例都如下所示: interface Worker
我有一个问题: - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInf
伙计们。我正在寻求帮助。这似乎是一个非常简单的任务,但我可以解决一整天。我正在尝试使用容器 View 创建侧面菜单。当用户按下“更多”按钮(barButtonItem)时,整个 View 向右滑动并出
我正在努力将 UIWebView 迁移到 WKWebView。我已经更改了所有委托(delegate)方法。我需要 WKWebView 委托(delegate)方法等于下面的 UIWebView 委托
我正在学习 VB.NET 中的委托(delegate),但对委托(delegate)类型感到困惑。在阅读有关委托(delegate)的内容时,我了解到委托(delegate)是一种数据类型,可以引用具
我有一个用 Objetive-C 构建的框架。该框架用于连接蓝牙设备并与之交互。 在演示代码中,Objetive-C 委托(delegate)函数如下所示。演示代码由框架创建者提供。 -(void)b
//NewCharts.h #import @interface NewCharts : UIViewController @property(nonatomic,retain)IBOutlet U
我正在努力了解 async/await 并认为我确实了解有关用法的一些事情。但仍然不太清楚在下面的场景中实际好处是什么。 查看 Task.Run 用法。第一种方法使用普通委托(delegate)并使用
我已经尝试了在我的网站上使用 openID 委托(delegate)的所有可能选项,但没有一个方法对我有用。 我的 HTML 文件的 head 部分有“link rel”标签。 我在 HTML 文件的
如何快速创建一个委托(delegate),即 NSUserNotificationCenterDelegate? 最佳答案 这里有一些关于两个 View Controller 之间委托(delegat
我有一个带有数据源的 NSComboBox,当您单击三角形并通过单击它选择其中一个项目时,它可以完美运行。但是,我还希望它允许用户在框中键入以使用自动完成来选择名称。目前,当用户键入时,我希望选择的项
我在代码中定义了以下类和委托(delegate)(为简洁起见,剪掉了许多其他行)。 Public Delegate Sub TimerCallback(canceled As Boolean) Pub
我使用 ansible 2.1 并且我想使用 delegate_to 向一组主机运行命令。我使用 localhost 作为主机参数,并且我想将“touch”命令委托(delegate)给两个 cls
我想通过重载为我的类实现几个构造函数。据我了解,遵循 DRY 原则的惯用方式是使用一种称为委托(delegate)构造函数的功能。我也看到了关于在任何地方使用引用参数并不惜一切代价避免使用指针的想法,
代表们会导致内存泄漏吗? 我的意思是,例如如果一个类A包含一个ADelegate,并且后者指向BMethod(属于B类),这可以防止GC收集A类或B类吗? 如果是这样,我们如何“释放”代表(设置ADe
委托(delegate)命令和路由命令有什么区别? 我读了一些文章说在 MVVM 上使用委托(delegate)命令而不是路由命令。 那么当我们使用 MVVM 时,Delegate Command 相
我是一名优秀的程序员,十分优秀!