thread loop and handler
来源:互联网 发布:淘宝解除手机绑定 编辑:程序博客网 时间:2024/05/18 00:17
1.什么是java thread?
libcore/libart/src/main/java/java/lang/Thread.java
/**
* A {@code Thread} is a concurrent unit of execution. It has its own call stack
* for methods being invoked, their arguments and local variables. Each application
* has at least one thread running when it is started, the main thread, in the main
* {@link ThreadGroup}. The runtime keeps its own threads in the system thread
* group.
*
* <p>There are two ways to execute code in a new thread.
* You can either subclass {@code Thread} and overriding its {@link #run()} method,
* or construct a new {@code Thread} and pass a {@link Runnable} to the constructor.
* In either case, the {@link #start()} method must be called to actually execute
* the new {@code Thread}.
*
* <p>Each {@code Thread} has an integer priority that affect how the thread is
* scheduled by the OS. A new thread inherits the priority of its parent.
* A thread's priority can be set using the {@link #setPriority(int)} method.
*/
public class Thread implements Runnable {
}
java thread的状态:
/**
* A representation of a thread's state. A given thread may only be in one
* state at a time.
*/
public enum State {
/**
* The thread has been created, but has never been started.
*/
NEW,
/**
* The thread may be run.
*/
RUNNABLE,
/**
* The thread is blocked and waiting for a lock.
*/
BLOCKED,
/**
* The thread is waiting.
*/
WAITING,
/**
* The thread is waiting for a specified amount of time.
*/
TIMED_WAITING,
/**
* The thread has been terminated.
*/
TERMINATED
}
thread的构造函数最终到调用了create: 从中可以看出参数的意义
/**
* Constructs a new {@code Thread} with a {@code Runnable} object, the given
* name and belonging to the {@code ThreadGroup} passed as parameter.
*
* @param group
* {@code ThreadGroup} to which the new {@code Thread} will
* belong
* @param runnable
* a {@code Runnable} whose method <code>run</code> will be
* executed by the new {@code Thread}
* @param threadName
* the name for the {@code Thread} being created
* @param stackSize
* a stack size for the new {@code Thread}. This has a highly
* platform-dependent interpretation. It may even be ignored
* completely.
* @throws IllegalThreadStateException
* if <code>group.destroy()</code> has already been done
* @see java.lang.ThreadGroup
* @see java.lang.Runnable
*/
public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
if (threadName == null) {
throw new NullPointerException("threadName == null");
}
create(group, runnable, threadName, stackSize);
}
private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
Thread currentThread = Thread.currentThread();
if (group == null) {
group = currentThread.getThreadGroup();
}
if (group.isDestroyed()) {
throw new IllegalThreadStateException("Group already destroyed");
}
this.group = group;
synchronized (Thread.class) {
id = ++Thread.count;
}
if (threadName == null) {
this.name = "Thread-" + id;
} else {
this.name = threadName;
}
this.target = runnable;
this.stackSize = stackSize;
this.priority = currentThread.getPriority();
this.contextClassLoader = currentThread.contextClassLoader;
// Transfer over InheritableThreadLocals.
if (currentThread.inheritableValues != null) {
inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
}
// add ourselves to our ThreadGroup of choice
this.group.addThread(this);
}
新线程的入口是start, 调用了natice层的创建线程的函数,java线程的栈包括三部分:kernel/native/java
/**
* Starts the new Thread of execution. The <code>run()</code> method of
* the receiver will be called by the receiver Thread itself (and not the
* Thread calling <code>start()</code>).
*
* @throws IllegalThreadStateException - if this thread has already started.
* @see Thread#run
*/
public synchronized void start() {
checkNotStarted();
hasBeenStarted = true;
nativeCreate(this, stackSize, daemon);
}
private native static void nativeCreate(Thread t, long stackSize, boolean daemon);
static void Thread_nativeCreate(JNIEnv* env, jclass, jobject java_thread, jlong stack_size,
jboolean daemon) {
Thread::CreateNativeThread(env, java_thread, stack_size, daemon == JNI_TRUE);
}
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;
Runtime* runtime = Runtime::Current();
// 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()));
pthread_create_result = pthread_create(&new_pthread,
&attr,
Thread::CreateCallback,
child_thread);
}
int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
void* (*start_routine)(void*), void* arg) {
int rc = clone(__pthread_start, child_stack, flags, thread, &(thread->tid), tls, &(thread->tid));
}
新创建的线程会调用java层的 runnable的run:
/**
* Calls the <code>run()</code> method of the Runnable object the receiver
* holds. If no Runnable is set, does nothing.
*
* @see Thread#start
*/
public void run() {
if (target != null) {
target.run();
}
}
2. 使用线程的方法:
subclass {@code Thread} and overriding its {@link #run()} method:
执行后,该线程就退出
new Thread() {
@Override
public void run() {
Utils.logI(TAG, "onReceive currentTimeMills:" + System.currentTimeMillis());
String action = intent.getAction();
String res = intent.getStringExtra(action);
parseData(mContext,res);
}
}.start();
一句话:线程就是重写 run()然后调用start
3. 为线程引入looper[message queue]
/**
* Handy class for starting a new thread that has a looper. The looper can then be
* used to create handler classes. Note that start() must still be called.
*/
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
}
HandlerThread重构了run引入了Looper, 并等待处理Looper message queue中的message.
4. 向线程中引入向Looper中添加message、和具体怎样处理message的handler
/**
* A Handler allows you to send and process {@link Message} and Runnable
* objects associated with a thread's {@link MessageQueue}. Each Handler
* instance is associated with a single thread and that thread's message
* queue. When you create a new Handler, it is bound to the thread /
* message queue of the thread that is creating it -- from that point on,
* it will deliver messages and runnables to that message queue and execute
* them as they come out of the message queue.
*
* <p>There are two main uses for a Handler:
(1) to schedule messages and runnables to be executed as some point in the future;
(2) to enqueue an action to be performed on a different thread than your own.
*
* <p>Scheduling messages is accomplished with the
* {@link #post}, {@link #postAtTime(Runnable, long)},
* {@link #postDelayed}, {@link #sendEmptyMessage},
* {@link #sendMessage}, {@link #sendMessageAtTime}, and
* {@link #sendMessageDelayed} methods. The <em>post</em> versions allow
* you to enqueue Runnable objects to be called by the message queue when
* they are received; the <em>sendMessage</em> versions allow you to enqueue
* a {@link Message} object containing a bundle of data that will be
* processed by the Handler's {@link #handleMessage} method (requiring that
* you implement a subclass of Handler).
*
* <p>When posting or sending to a Handler, you can either
* allow the item to be processed as soon as the message queue is ready
* to do so, or specify a delay before it gets processed or absolute time for
* it to be processed. The latter two allow you to implement timeouts,
* ticks, and other timing-based behavior.
*
* <p>When a
* process is created for your application, its main thread is dedicated to
* running a message queue that takes care of managing the top-level
* application objects (activities, broadcast receivers, etc) and any windows
* they create. You can create your own threads, and communicate back with
* the main application thread through a Handler. This is done by calling
* the same <em>post</em> or <em>sendMessage</em> methods as before, but from
* your new thread. The given Runnable or Message will then be scheduled
* in the Handler's message queue and processed when appropriate.
*/
怎样使用?
mThread = new HandlerThread(TAG);
mThread.start();
mHandler = new Handler(mThread.getLooper());
如:
mHandler.post(new Runnable() {
@Override
public void run() {
Utils.logI(TAG, "onReceive currentTimeMills:" + System.currentTimeMillis());
String action = intent.getAction();
String res = intent.getStringExtra(action);
parseData(mContext,res);
}
});
sendMessage?
5.BackgroundThread: 获得一个handler,通过handler post(runnable)
/**
* Shared singleton background thread for each process.
*/
public final class BackgroundThread extends HandlerThread {
private static BackgroundThread sInstance;
private static Handler sHandler;
private BackgroundThread() {
super("android.bg", android.os.Process.THREAD_PRIORITY_BACKGROUND);
}
private static void ensureThreadLocked() {
if (sInstance == null) {
sInstance = new BackgroundThread();
sInstance.start();
sHandler = new Handler(sInstance.getLooper());
}
}
public static BackgroundThread get() {
synchronized (BackgroundThread.class) {
ensureThreadLocked();
return sInstance;
}
}
public static Handler getHandler() {
synchronized (BackgroundThread.class) {
ensureThreadLocked();
return sHandler;
}
}
}
6. thread的退出
libcore/libart/src/main/java/java/lang/Thread.java
/**
* A {@code Thread} is a concurrent unit of execution. It has its own call stack
* for methods being invoked, their arguments and local variables. Each application
* has at least one thread running when it is started, the main thread, in the main
* {@link ThreadGroup}. The runtime keeps its own threads in the system thread
* group.
*
* <p>There are two ways to execute code in a new thread.
* You can either subclass {@code Thread} and overriding its {@link #run()} method,
* or construct a new {@code Thread} and pass a {@link Runnable} to the constructor.
* In either case, the {@link #start()} method must be called to actually execute
* the new {@code Thread}.
*
* <p>Each {@code Thread} has an integer priority that affect how the thread is
* scheduled by the OS. A new thread inherits the priority of its parent.
* A thread's priority can be set using the {@link #setPriority(int)} method.
*/
public class Thread implements Runnable {
}
java thread的状态:
/**
* A representation of a thread's state. A given thread may only be in one
* state at a time.
*/
public enum State {
/**
* The thread has been created, but has never been started.
*/
NEW,
/**
* The thread may be run.
*/
RUNNABLE,
/**
* The thread is blocked and waiting for a lock.
*/
BLOCKED,
/**
* The thread is waiting.
*/
WAITING,
/**
* The thread is waiting for a specified amount of time.
*/
TIMED_WAITING,
/**
* The thread has been terminated.
*/
TERMINATED
}
thread的构造函数最终到调用了create: 从中可以看出参数的意义
/**
* Constructs a new {@code Thread} with a {@code Runnable} object, the given
* name and belonging to the {@code ThreadGroup} passed as parameter.
*
* @param group
* {@code ThreadGroup} to which the new {@code Thread} will
* belong
* @param runnable
* a {@code Runnable} whose method <code>run</code> will be
* executed by the new {@code Thread}
* @param threadName
* the name for the {@code Thread} being created
* @param stackSize
* a stack size for the new {@code Thread}. This has a highly
* platform-dependent interpretation. It may even be ignored
* completely.
* @throws IllegalThreadStateException
* if <code>group.destroy()</code> has already been done
* @see java.lang.ThreadGroup
* @see java.lang.Runnable
*/
public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
if (threadName == null) {
throw new NullPointerException("threadName == null");
}
create(group, runnable, threadName, stackSize);
}
private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
Thread currentThread = Thread.currentThread();
if (group == null) {
group = currentThread.getThreadGroup();
}
if (group.isDestroyed()) {
throw new IllegalThreadStateException("Group already destroyed");
}
this.group = group;
synchronized (Thread.class) {
id = ++Thread.count;
}
if (threadName == null) {
this.name = "Thread-" + id;
} else {
this.name = threadName;
}
this.target = runnable;
this.stackSize = stackSize;
this.priority = currentThread.getPriority();
this.contextClassLoader = currentThread.contextClassLoader;
// Transfer over InheritableThreadLocals.
if (currentThread.inheritableValues != null) {
inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
}
// add ourselves to our ThreadGroup of choice
this.group.addThread(this);
}
新线程的入口是start, 调用了natice层的创建线程的函数,java线程的栈包括三部分:kernel/native/java
/**
* Starts the new Thread of execution. The <code>run()</code> method of
* the receiver will be called by the receiver Thread itself (and not the
* Thread calling <code>start()</code>).
*
* @throws IllegalThreadStateException - if this thread has already started.
* @see Thread#run
*/
public synchronized void start() {
checkNotStarted();
hasBeenStarted = true;
nativeCreate(this, stackSize, daemon);
}
private native static void nativeCreate(Thread t, long stackSize, boolean daemon);
static void Thread_nativeCreate(JNIEnv* env, jclass, jobject java_thread, jlong stack_size,
jboolean daemon) {
Thread::CreateNativeThread(env, java_thread, stack_size, daemon == JNI_TRUE);
}
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;
Runtime* runtime = Runtime::Current();
// 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()));
pthread_create_result = pthread_create(&new_pthread,
&attr,
Thread::CreateCallback,
child_thread);
}
int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
void* (*start_routine)(void*), void* arg) {
int rc = clone(__pthread_start, child_stack, flags, thread, &(thread->tid), tls, &(thread->tid));
}
新创建的线程会调用java层的 runnable的run:
/**
* Calls the <code>run()</code> method of the Runnable object the receiver
* holds. If no Runnable is set, does nothing.
*
* @see Thread#start
*/
public void run() {
if (target != null) {
target.run();
}
}
2. 使用线程的方法:
subclass {@code Thread} and overriding its {@link #run()} method:
执行后,该线程就退出
new Thread() {
@Override
public void run() {
Utils.logI(TAG, "onReceive currentTimeMills:" + System.currentTimeMillis());
String action = intent.getAction();
String res = intent.getStringExtra(action);
parseData(mContext,res);
}
}.start();
一句话:线程就是重写 run()然后调用start
3. 为线程引入looper[message queue]
/**
* Handy class for starting a new thread that has a looper. The looper can then be
* used to create handler classes. Note that start() must still be called.
*/
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
}
HandlerThread重构了run引入了Looper, 并等待处理Looper message queue中的message.
4. 向线程中引入向Looper中添加message、和具体怎样处理message的handler
/**
* A Handler allows you to send and process {@link Message} and Runnable
* objects associated with a thread's {@link MessageQueue}. Each Handler
* instance is associated with a single thread and that thread's message
* queue. When you create a new Handler, it is bound to the thread /
* message queue of the thread that is creating it -- from that point on,
* it will deliver messages and runnables to that message queue and execute
* them as they come out of the message queue.
*
* <p>There are two main uses for a Handler:
(1) to schedule messages and runnables to be executed as some point in the future;
(2) to enqueue an action to be performed on a different thread than your own.
*
* <p>Scheduling messages is accomplished with the
* {@link #post}, {@link #postAtTime(Runnable, long)},
* {@link #postDelayed}, {@link #sendEmptyMessage},
* {@link #sendMessage}, {@link #sendMessageAtTime}, and
* {@link #sendMessageDelayed} methods. The <em>post</em> versions allow
* you to enqueue Runnable objects to be called by the message queue when
* they are received; the <em>sendMessage</em> versions allow you to enqueue
* a {@link Message} object containing a bundle of data that will be
* processed by the Handler's {@link #handleMessage} method (requiring that
* you implement a subclass of Handler).
*
* <p>When posting or sending to a Handler, you can either
* allow the item to be processed as soon as the message queue is ready
* to do so, or specify a delay before it gets processed or absolute time for
* it to be processed. The latter two allow you to implement timeouts,
* ticks, and other timing-based behavior.
*
* <p>When a
* process is created for your application, its main thread is dedicated to
* running a message queue that takes care of managing the top-level
* application objects (activities, broadcast receivers, etc) and any windows
* they create. You can create your own threads, and communicate back with
* the main application thread through a Handler. This is done by calling
* the same <em>post</em> or <em>sendMessage</em> methods as before, but from
* your new thread. The given Runnable or Message will then be scheduled
* in the Handler's message queue and processed when appropriate.
*/
怎样使用?
mThread = new HandlerThread(TAG);
mThread.start();
mHandler = new Handler(mThread.getLooper());
如:
mHandler.post(new Runnable() {
@Override
public void run() {
Utils.logI(TAG, "onReceive currentTimeMills:" + System.currentTimeMillis());
String action = intent.getAction();
String res = intent.getStringExtra(action);
parseData(mContext,res);
}
});
sendMessage?
5.BackgroundThread: 获得一个handler,通过handler post(runnable)
/**
* Shared singleton background thread for each process.
*/
public final class BackgroundThread extends HandlerThread {
private static BackgroundThread sInstance;
private static Handler sHandler;
private BackgroundThread() {
super("android.bg", android.os.Process.THREAD_PRIORITY_BACKGROUND);
}
private static void ensureThreadLocked() {
if (sInstance == null) {
sInstance = new BackgroundThread();
sInstance.start();
sHandler = new Handler(sInstance.getLooper());
}
}
public static BackgroundThread get() {
synchronized (BackgroundThread.class) {
ensureThreadLocked();
return sInstance;
}
}
public static Handler getHandler() {
synchronized (BackgroundThread.class) {
ensureThreadLocked();
return sHandler;
}
}
}
6. thread的退出
0 0
- thread loop and handler
- Handler Thread Loop形象比喻
- Android Thread,Handler,Loop用法介绍
- Android Thread,Handler,Loop用法介绍
- Android Thread,Handler,Loop,Message,HandlerThread总结
- Handler and Thread
- Handler and Thread
- Android Thread and Handler
- Thread loop of C++ and Java
- android handler, thread and looper
- 浅谈Handler,Loop,MessageQueue,Thread的小秘密
- Android Dev Intro - Thread Looper and Handler
- Handler + Thread
- handler thread
- Handler Thread
- Handler、Loop和MessageQueue
- handler,loop,handlerthread
- Handler、Message、Loop
- Windows的全局名称锁与共享问题
- 兔子迭代问题
- 支付宝手机网站支付 错误代码 insufficient-isv-permissions 错误原因: ISV权限不足
- SQL中使用update inner join和delete inner join
- 使用java向FTP上传或下载压缩文件时的问题
- thread loop and handler
- PT2272解码相关知识 互锁 自锁
- NiFi源码整理
- PHP实现留言板功能
- JSP
- PowerDesigner
- 笔记:起非阻塞服务的方法(之一)
- 数独问题
- (三)简单工厂模式详解