1.线程的状态
java的线程是通过java.lang.Thread类来实现的。
1.1创建
调用完构造函数后,线程就为创建状态。
1.2就绪
调用start()方法后,所处的状态。
1.3运行
正常的运行。
1.4阻塞
资源等待的状态。
1.5死亡
run()方法执行完毕后,该线程就死掉了。注意不能再次调用此线程的start()方法。
2.常用函数
java.lang.Thread.Thread(Runnable target, String name)
创建新线程,并指定线程的名字。
java.lang.Thread.Thread(ThreadGroup group, Runnable target, String name)
创建新线程,并指定线程的名字和所属线程组。
void java.lang.Thread.start()
让线程置于就绪状态,等待操作系统调度。
问:它与run()有什么区别呢?
答:start()是异步的,会新起一个线程,在新的线程中调用run()方法。直接调用run()就是在当前线程中执行同步的方法。
Thread java.lang.Thread.currentThread()
返回当前线程。
String java.lang.Thread.getName()
返回线程名称。
boolean java.lang.Thread.isDaemon()
是否是一个后台线程。
void java.lang.Thread.yield()
告诉操作系统此时可以进行线程切换。使用此方法有助于暴露线程不安全问题导致的异常现象。
java.lang.Thread.sleep(long millis, int nanos)
当前线程睡眠(millis 毫秒+nanos纳秒)。此方法会被TimeUnit这个枚举类型调用,可见:void java.util.concurrent.TimeUnit.sleep(long timeout)。
void java.lang.Thread.join(long millis)
此函数是同步的,当线程结束或等待达到超时时间后返回。
3.线程中断
Thread 的stop()与destory()方法被废弃,直接调用会有异常,见下:
@Deprecated public void destroy() { throw new NoSuchMethodError(); }
所以现在你不能暴力地中断一个线程,只能让线程自己来配合。
void java.lang.Thread.interrupt()
Thread类有一个布尔字段isInterrupted,用来标记自己是否被中断。调用此方法会置这个变量为true。如果此线程被join()、wait()、sleep()方法阻塞,那么调用interrupt()方法时会引起InterruptedException异常。
boolean java.lang.Thread.isInterrupted()
返回上面说的isInterrupted布尔变量。
3.1 例子
run()里面的whilr(true) 被 替代,这样更优雅。一旦run()函数执行完毕,一个线程也就完成了它的使命。
@Override public void run() { while(true){ //do something } } //above and below is a contrast. @Override public void run() { while(!Thread.currentThread().isInterrupted()){ //do something } }
4.线程相关接口
4.1 Runnable
java.lang.Runnable
它是一个接口,有run()方法。
接口定义见下:
@FunctionalInterface public interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }
想要被作为新线程运行的类需要实现Runnable接口,在run()函数中完成待处理的任务。
1.定义类A继承接口Runnable,并实现函数 void run();
2.用A的对象构造Thread对象。然后调用start()函数。
注意:start()函数为异步调用,立即返回啦。
4.2 Callable
java.lang.Callable
它是一个接口,有call()方法,用于具有返回值的多线程任务。
接口定义见下。
@FunctionalInterface public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
例子:
4.3 Future
java.util.concurrent.Future<E>
Future对象代表着一个异步操作的结果。调用此对象的isDone()方法来查询任务是否已完成,它是异步的。调用get()方法获取线程执行结果,它是同步的,在结果准备就绪前一直阻塞。
它的接口定义见下:
public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }