JAVA线程启动时间的问题。。。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA线程启动时间的问题。。。相关的知识,希望对你有一定的参考价值。
程序运行以后,需要一个线程每天固定时间启动(比如说两点钟)。
不知道就这么一直让线程休眠上24小时执行一次好不好?
还有,非常急切的问题。第一次运行的时间怎么确定?除了一直判断时间直到正确的时候,还有没有其他更好的办法?
Timer有个scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 方法,可以firstTime设置城下一个你要执行的时间,将period设置为24小时,这样就实现了固定时间执行程序的功能 参考技术A 第一次运行的扑捉系统时间 参考技术B linux 建议你 crontab 定时执行
windows 计划任务
否则. 每1分钟判断一次时间. 如果符合时间片则执行. 否则. sleep一分钟 参考技术C 用JAVA的TIMER类可以实现定时每天两点执行。 参考技术D 这个需求可以使用定时任务。查查这方面的资料。
java.lang.InternalError 线程在运行时关闭期间启动
【中文标题】java.lang.InternalError 线程在运行时关闭期间启动【英文标题】:java.lang.InternalError Thread starting during runtime shutdown 【发布时间】:2016-04-15 17:18:53 【问题描述】:我们无法获得此异常的确切原因。有谁知道,为什么这个异常发生在android应用程序中?提前致谢。
这是 Exception 的完整堆栈跟踪:
Fatal Exception: java.lang.InternalError: Thread starting during runtime shutdown
at java.lang.Thread.nativeCreate(Thread.java)
at java.lang.Thread.start(Thread.java:1063)
at org.apache.http.impl.conn.tsccm.AbstractConnPool.enableConnectionGC(AbstractConnPool.java:145)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.createConnectionPool(ThreadSafeClientConnManager.java:125)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.<init>(ThreadSafeClientConnManager.java:103)
at org.acra.util.HttpRequest.getHttpClient(HttpRequest.java:214)
at org.acra.util.HttpRequest.send(HttpRequest.java:141)
at org.acra.sender.HttpSender.send(HttpSender.java:225)
at org.acra.SendWorker.sendCrashReport(SendWorker.java:179)
at org.acra.SendWorker.checkAndSendReports(SendWorker.java:141)
at org.acra.SendWorker.run(SendWorker.java:77)
【问题讨论】:
写完整的调用栈跟踪。 这不是 ANR。应用程序在特定屏幕上崩溃。 github.com/ACRA/acra/issues/196 【参考方案1】:void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size, bool is_daemon)
CHECK(java_peer != nullptr);
Thread* self = static_cast<JNIEnvExt*>(env)->self;
if (VLOG_IS_ON(threads))
ScopedObjectAccess soa(env);
ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
mirror::String* java_name = reinterpret_cast<mirror::String*>(f->GetObject(
soa.Decode<mirror::Object*>(java_peer)));
std::string thread_name;
if (java_name != nullptr)
thread_name = java_name->ToModifiedUtf8();
else
thread_name = "(Unnamed)";
VLOG(threads) << "Creating native thread for " << thread_name;
self->Dump(LOG(INFO));
Runtime* runtime = Runtime::Current();
// Atomically start the birth of the thread ensuring the runtime isn't shutting down.
bool thread_start_during_shutdown = false;
MutexLock mu(self, *Locks::runtime_shutdown_lock_);
if (runtime->IsShuttingDownLocked())
thread_start_during_shutdown = true;
else
runtime->StartThreadBirth();
if (thread_start_during_shutdown) //At there!!!
ScopedLocalRef<jclass> error_class(env, env->FindClass("java/lang/InternalError"));
env->ThrowNew(error_class.get(), "Thread starting during runtime shutdown");
return;
Thread* child_thread = new Thread(is_daemon);
// Use global JNI ref to hold peer live while child thread starts.
child_thread->tlsPtr_.jpeer = env->NewGlobalRef(java_peer);
stack_size = FixStackSize(stack_size);
// Thread.start is synchronized, so we know that nativePeer is 0, and know that we're not racing to
// assign it.
env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer,
reinterpret_cast<jlong>(child_thread));
// Try to allocate a JNIEnvExt for the thread. We do this here as we might be out of memory and
// do not have a good way to report this on the child's side.
std::unique_ptr<JNIEnvExt> child_jni_env_ext(
JNIEnvExt::Create(child_thread, Runtime::Current()->GetJavaVM()));
int pthread_create_result = 0;
if (child_jni_env_ext.get() != nullptr)
pthread_t new_pthread;
pthread_attr_t attr;
child_thread->tlsPtr_.tmp_jni_env = child_jni_env_ext.get();
CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), "new thread");
CHECK_PTHREAD_CALL(pthread_attr_setdetachstate, (&attr, PTHREAD_CREATE_DETACHED),
"PTHREAD_CREATE_DETACHED");
CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, stack_size), stack_size);
pthread_create_result = pthread_create(&new_pthread,
&attr,
Thread::CreateCallback,
child_thread);
CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), "new thread");
if (pthread_create_result == 0)
// pthread_create started the new thread. The child is now responsible for managing the
// JNIEnvExt we created.
// Note: we can't check for tmp_jni_env == nullptr, as that would require synchronization
// between the threads.
child_jni_env_ext.release();
return;
// Either JNIEnvExt::Create or pthread_create(3) failed, so clean up.
MutexLock mu(self, *Locks::runtime_shutdown_lock_);
runtime->EndThreadBirth();
// Manually delete the global reference since Thread::Init will not have been run.
env->DeleteGlobalRef(child_thread->tlsPtr_.jpeer);
child_thread->tlsPtr_.jpeer = nullptr;
delete child_thread;
child_thread = nullptr;
// TODO: remove from thread group?
env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer, 0);
std::string msg(child_jni_env_ext.get() == nullptr ?
"Could not allocate JNI Env" :
StringPrintf("pthread_create (%s stack) failed: %s",
PrettySize(stack_size).c_str(), strerror(pthread_create_result)));
ScopedObjectAccess soa(env);
soa.Self()->ThrowOutOfMemoryError(msg.c_str());
【讨论】:
你不觉得解释会更好以上是关于JAVA线程启动时间的问题。。。的主要内容,如果未能解决你的问题,请参考以下文章
如何验证线程中的命令是不是在Java中成功启动并且可以启动另一个线程?
java.lang.InternalError 线程在运行时关闭期间启动