一、线程基础
1、runnable是个只有一个方法的接口
public interface Runnable
{
void run();
}
2、两种方法创建一个线程
(1)先创建一个runnable实例,再根据这个实例创建线程
//创建一个runnable实例
Runnable r = () ->
{
task code
};
//根据刚刚创造的实例创建一个线程
var t = new Thread(r);
//启动线程
t.start();
(2)新建一个类继承Thread类,并实现他的run方法,但注意,这个方法并不推荐使用,因为,runnable实例是要进行的任务,而Thread是运行任务的机制,你应该将要进行的任务和任务运行的机制解耦。
class MyThread extends Thread
{
public void run()
{
task code
}
}
3、几个关键的API
java.lang.Thread 1.0• Thread(Runnable target)constructs a new thread that calls the run() method of the specified target.• void start()starts this thread, causing the run() method to be called. This method will return immediately. The new thread runs concurrently.• void run()calls the run method of the associated Runnable.• static void sleep(long millis)sleeps for the given number of milliseconds.
二、 线程的状态
线程有六个状态
1、刚刚new出来的线程是new状态,start之后就会进入runnable状态,run方法返回后,或是run方法中有一个异常未被捕捉,那么线程就会进入terminated状态。
2、线程尝试获得一个当前别的线程持有的intrinsic object lock的时候会进入block状态。
3、线程等待一个condition的时候会进入waiting状态
4、线程在调用Thread.sleep和时间版本的Object.wait, Thread.join, Lock.tryLock, 和Condition.await时,会进入timed waiting状态。
5、上面那张图是java核心技术卷里的,面向中间件考试要看下面这张图
6、几个关键的API
java.lang.Thread 1.0• void join()waits for the specified thread to terminate.• void join(long millis)waits for the specified thread to die or for the specified number of milliseconds to pass.• Thread.State getState() 5gets the state of this thread: one of NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, or TERMINATED.• void stop()stops the thread. This method is deprecated.• void suspend()suspends this thread’s execution. This method is deprecated for removal.• void resume()resumes this thread. This method is only valid after suspend() has been invoked. This method is deprecated for removal.
三、线程的性质
1、interrupt(), interrupted(), isInterrupted()
Thread t = new Thread();
t.interrupt();
boolean b = t.isInterrupted();
boolean c = Thread.interrupted();
首先,interrupted()是静态方法,调用Thread.interrupted()等于Thread.currentThread().isInterrupted(), 也就是查看当前进程的中断状态
其次,interrupt()是将该线程中的interrupted状态(一个布尔成员变量)设为true。
再次,interrupted(), isInterrupted()都是查看线程的interrupted状态。
2、这段代码说明,对一个interrupt状态为ture的线程调用方法使他阻塞,例如调用sleep,会抛出一个InterruptedException,程序员可以通过这个catch异常来判断该线程的interrupt状态,从而做些操作。
Runnable r = () ->
{
try {
/*. . .*/
while (/*more work to do*/) {
/*do more work*/
Thread.sleep(delay);
}
} catch (InterruptedException e) {
// thread was interrupted during sleep
} finally {
/*cleanup,if required*/
}
// exiting the run method terminates the thread
};
3、Daemon Thread 守护线程
你可以用
t.setDaemon(true);
来将一个线程变为守护线程,守护线程通常没有自己的任务,他们产生就是为了服务别的线程,例如一个定时器,亦或者一个定时清理缓存的线程。当只有守护线程在运行的时候,JVM就会退出,因为守护线程只为了服务别的线程,当只有守护线程,没有别的线程需要服务的时候,那程序就没有必要执行了。
4、给你的线程起个名字
var t = new Thread(runnable);
t.setName("Web crawler");
5、未捕获异常的处理器
unchecked的异常会使线程终止,在线程死亡之前,他会被传递到一个用于处理unchecked异常的处理器。
这个处理器必须属于一个实现了Thread.UncaughtExceptionHandler接口的类,这个接口只有一个方法,
void uncaughtException(Thread t, Throwable e)
你可以用下面这个方法来为所有的线程设置默认的处理器。
Thread.setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler)
也可以用下面的方法为某一个线程设置处理器
t.setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler)
6、线程优先级
java的线程有1-10十个优先级,默认的是5,JVM会把java的线程优先级映射到操作系统的线程优先级上。在调度的时候会选择优先级最高的那一个。在旧版本的java中没有使用操作系统的优先级,所以线程优先级可能很有用,但现在不要使用线程优先级了。