Thread基础
记录Java Thread的基础点。线程的实现 线程的定义有两种方式
- 继承Thread类
- 实现Runnable接口
Thread thread = new Thread();
thread.start();
// 或者
Thread runnable = new Thread(new Runnable());
runnable.start();
run() 线程实际运行调用的是run()方法。
- 其中Thread类中的run() 实际是调用传入Runnable对象的run()方法
@Override
public void run() {
if (target != null) {
target.run();
}
}
线程状态
NEW, // 新建,创建后尚未启动的线程处于这种状态RUNNABLE, // 运行
// 处于这种状态的线程有可能正在执行也有可能正在等待CPU分配执行时间BLOCKED, // 阻塞WAITING, // 无限期等待
// 处于这种状态CPU不会分配执行时间
// 需要其他线程唤醒TIMED_WAITING, // 限期等待
// 处于这种状态CPU不会分配执行时间
// 不需要其他线程唤醒,在一定时间之后会由系统自动唤醒TERMINATED;
// 结束,线程已经结束执行
线程状态转换关系图:
文章图片
java-thread-status.jpg 线程的属性和方法 设置优先级
public final void setPriority(int newPriority)
每个类都有自己的优先级,一般property用1-10的整数表示,默认优先级是5,优先级最高是10;优先级高的线程并不一定比优先级低的线程执行的机会高,只是执行的机率高;默认一个线程的优先级和创建他的线程优先级相同。
sleep
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos) throws InterruptedException
可以使用TimeUnit的sleep方法
TimeUnit.MILLISECONDS.sleep(500L);
// 内部实现还是调用Thread.sleep()实现的,源码如下
public void sleep(long timeout) throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
Thread.sleep(ms, ns);
}
}
当前线程睡眠/millis的时间(millis指定睡眠时间是其最小的不执行时间,因为sleep(millis)休眠到达后,无法保证会被JVM立即调度);sleep()是一个静态方法(static method) ,所以他不会停止其他的线程也处于休眠状态;线程sleep()时不会失去拥有的对象锁。作用:保持对象锁,让出CPU,调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留一定的时间给其他线程执行的机会;
yield
public static native void yield();
让出CPU的使用权,给其他线程执行机会、让同等优先权的线程运行(但并不保证当前线程会被JVM再次调度、使该线程重新进入Running状态),如果没有同等优先权的线程,那么yield()方法将不会起作用。
它仅能是一个线程从运行状态转换到可运行状态,而不是等待或阻塞状态。
join
public final void join() throws InterruptedExceptionpublic final synchronized void join(long mills)
throws InterruptedExceptionpublic final synchronized void join(long millis, int nanos) throws InterruptedException
使用该方法的线程会在此之间执行完毕后再往下继续执行。
特殊的线程方法 object.wait()
// 存在对象
Object obj ;
// 使用
synchronized(obj){
obj.wait();
// 无限等待
obj.wait(1000L);
// 设定等待超时时间(有限等待)
}
当一个线程执行到wait()方法时,他就进入到一个和该对象相关的等待池(Waiting Pool)中,同时失去了对象的机锁—暂时的,wait后还要返还对象锁。当前线程必须拥有当前对象的锁,如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常,所以wait()必须在synchronized 代码块中调用。
object.notify()/notifyAll()
【Thread基础】唤醒在当前对象等待池中等待的第一个线程/所有线程。notify()/notifyAll()也必须拥有相同对象锁,否则也会抛出IllegalMonitorStateException异常。
推荐阅读
- 20170612时间和注意力开销记录
- Python基础|Python基础 - 练习1
- 【剽悍读书营成长记录】2018年我收获了什么|【剽悍读书营成长记录】2018年我收获了什么 3357-小松
- Java|Java基础——数组
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 课后分享记录
- Java基础-高级特性-枚举实现状态机
- 营养基础学20180331(课间随笔)??
- iOS面试题--基础
- HTML基础--基本概念--跟着李南江学编程