我是一个Java新手,我想知道,如果我有以下典型的Java代码
public class MyApp {
public static void main(String[] args) {
try {
// do stuff
} catch {
// handle errors
} finally {
// clean up connections etc.
}
}
}
Run Code Online (Sandbox Code Playgroud)
JVM是否保证finally块始终运行?为了理解我来自哪里,我习惯了C/C++程序,如果你取消引用一个NULL指针就可能崩溃,之后就不能运行任何代码了.
但是,由于我理解Java和整个GC /托管内存业务,所以没有空指针解除引用的东西,一切都是可捕获的预期,所以我的程序没有真正的崩溃方式可以让它跳过最后,或者在那里?例如,在Python中,我通常会这样做
try:
# do stuff
except AnExceptionIKnewMightHappen:
# react in an appropriate way
except:
# log that weird error I had not known could happen
Run Code Online (Sandbox Code Playgroud)
我没有通过我的代码就没有任何应用程序死亡.
当然,如果操作系统由于某种原因导致进程终止(或者如果某些东西杀死了整个系统,比如拉动插件),那么Java就无法做到.此外,从PHP我知道你无法防范的非可捕获错误,即使解释器在它发生之后仍然存在(至少它能够输出正确的消息).
编辑:为了清楚起见(这并没有被任何人误解),让我补充一点,我在寻找代码中的内容,这可能会导致最终被绕过.所以指向System.exit是一个有用的提醒,即使我不明白为什么我想要做那样的事情.
退出JVM是一种相当明显的方式,我认为这是一个外部原因.该注释指出你还必须记住在JVM和应用程序继续运行时退出的线程的可能性非常有用,因为即使现在我看起来也很明显,我没有想到它.
我不太关心时间效率(操作很少),而是关于内存效率:我可以在没有暂时拥有所有值两次的情况下增长数组吗?
是否有更有效的方法来扩展大型阵列而不是创建新阵列并复制所有值?比如,用一个新的连接它?
将固定大小的数组存储在另一个数组中并重新分配/复制那个顶级数组怎么样?这会留下实际价值吗?
我知道ArrayList,但是我需要很多关于访问数组的控制,并且访问需要非常快.举例来说,我想我更喜欢a[i]到al.get(i).
我关心这个问题的主要原因是所讨论的数组(或许多这样的数组)可能很好地占据了主内存的足够大部分,因此在丢弃原始数据之前创建双倍大小的副本的通常策略可能不起作用出.这可能意味着我需要重新考虑整体战略(或我的硬件建议).
为了执行定期任务,我查看Timer并ScheduledThreadPoolExecutor(使用单个线程)并决定使用后者,因为在其中reference for Executors.newSingleThreadScheduledExecutor(),它说:
但请注意,如果此单个线程由于在关闭之前执行期间的故障而终止,则在需要执行后续任务时将使用新的线程.
我的计划是使用它作为一个保护措施,以防止我希望监视其他操作的监视程序代码中未被捕获的异常.我想确认并编写下面的测试,这很快就失败了.看来我做错了假设,或者我的测试有些不对劲?
这是代码:
@Test
public void testTimer() {
final AtomicInteger cTries = new AtomicInteger(0);
final AtomicInteger cSuccesses = new AtomicInteger(0);
TimerTask task = new TimerTask() {
@Override
public void run()
{
cTries.incrementAndGet();
if (true) {
throw new RuntimeException();
}
cSuccesses.incrementAndGet();
}
};
/*
Timer t = new Timer();
t.scheduleAtFixedRate(task, 0, 500);
*/
ScheduledExecutorService exe = Executors.newSingleThreadScheduledExecutor();
exe.scheduleAtFixedRate(task, 0, 500, TimeUnit.MILLISECONDS);
synchronized (this) {
try {
wait(3000);
} catch (InterruptedException e) { …Run Code Online (Sandbox Code Playgroud) 给定如下的关联数组,
$field_defaults = array(
'id' => 0,
'name' => 'new item',
'desc' => '',
'parent_id' => 0,
);
Run Code Online (Sandbox Code Playgroud)
我可以依赖array_keys()按照指定的顺序返回键吗?或者,更准确地说,由于PHP中的数组似乎具有稳定的顺序,根据这个答案,返回的键array_keys()是否与它们在输入数组中出现的顺序相同?该手册不给任何提示.
当我尝试这个时,他们似乎尊重原始秩序,但我希望能够依赖这种行为.
我有一个类根据消息的类将传入的消息映射到匹配的阅读器.所有消息类型都实现接口消息.读者在mapper类中注册,说明它将能够处理哪些消息类型.这些信息需要以某种方式存储在消息阅读器中,我的方法是private final从构造函数中设置一个数组.
现在,似乎我对泛型和/或数组有一些误解,我似乎无法弄清楚,请参阅下面的代码.它是什么?
public class HttpGetMessageReader implements IMessageReader {
// gives a warning because the type parameter is missing
// also, I actually want to be more restrictive than that
//
// private final Class[] _rgAccepted;
// works here, but see below
private final Class<? extends IMessage>[] _rgAccepted;
public HttpGetMessageReader()
{
// works here, but see above
// this._rgAccepted = new Class[1];
// gives the error "Can't create a generic array of Class<? extends IMessage>"
this._rgAccepted = new …Run Code Online (Sandbox Code Playgroud) 我确信它没有,但在Interwebs上寻找一个明确的答案让我有疑问.例如,我有一篇2008年的帖子,乍看之下看起来像个笑话,但看起来似乎很认真.
编辑: ...和被证明是寻找更接近后一个笑话.对困惑感到抱歉.实际上,该帖子的评论回答了我的问题,正如Nikhil正确指出的那样.
我们意识到CPython在这方面远远领先于我们,而且我们缺乏兼容性.在经过严肃的头脑风暴(以及几杯葡萄酒)之后,我们决定在Jython中引入Global Interpreter Lock将解决整个问题!
现在,这里的状态是什么?sourceforge上的"差异"页面根本没有提到GIL.有没有我忽略的官方消息来源?
另请注意,我知道正在进行的讨论GIL是否重要,但我暂时并不关心.
我有一个返回的方法long,有些情况下无法计算有效的结果.Double有NaN常数,这是不可表达的long.
我可以想到两个解决方案:
double,检查NaN并转换为long是否一切正常.是优先/更"爪哇"?还有其他方法吗/我错过了一些明显的东西吗?
我想,不,它们不是,因为每个进程当然都有自己的内存空间.
但整个JVM的实际工作原理是什么?对于我发布的每个Java程序,是否在单独的进程中有单独的JVM?在系统中运行的Java程序是否共享任何东西?操作系统和JVM实现之间是否存在差异?我可以让程序共享变量(即直接通过JVM而不是通常的IPC机制)吗?是否有更多异国情调的单进程JVM用于特殊目的?
一般来说,推荐的内容是关于JVM的内容吗?该规范?一些实现的源代码?网站?图书?
class A {
public synchronized void myOneMethod() {
// ...
}
}
class B extends A {
public synchronized void myOtherMethod() {
// ...
}
}
// ...
B myObject;
// ...
myObject.myOneMethod(); // acquires lock
myObject.myOtherMethod(); // same lock?
Run Code Online (Sandbox Code Playgroud)
我如何理解同步模型,我会说是的,确实如此,因为锁/监视器与实例myObject相关联,并且定义方法的位置并不重要.但我是对的吗?如果没有,为什么?如果是的话,你为什么确定,我不是?:-)
如果一个线程被中断,而里面Object.wait()还是Thread.join(),它抛出一个InterruptedException,它重置线程的中断状态.例如,如果我在这里有一个这样的循环Runnable.run():
while (!this._workerThread.isInterrupted()) {
// do something
try {
synchronized (this) {
this.wait(this._waitPeriod);
}
} catch (InterruptedException e) {
if (!this._isStopping()) {
this._handleFault(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
线程将在调用后继续运行interrupt().这意味着我必须通过在循环条件中检查自己的停止标志,重新抛出异常或添加一个来明确地突破循环break.
现在,这不是一个问题,因为这种行为有很好的记录,并不妨碍我按照我想要的方式做任何事情.但是,我似乎并不理解它背后的概念:为什么抛出异常后线程不再被视为中断?如果您获得中断状态interrupted()而不是isInterrupted(),那么也会发生类似的行为,那么,线程也只会出现一次中断.
我在做什么不寻常的事吗?例如,捕获InterruptedException循环外部是否更常见?
(虽然我不是一个初学者,但我标记了这个"初学者",因为对我来说这看起来像是一个非常基本的问题,看着它.)
java ×8
arrays ×1
concurrency ×1
finally ×1
generics ×1
jvm ×1
jython ×1
performance ×1
php ×1
python ×1
threadpool ×1
types ×1