Java多线程①——线程知识梳理

  • 线程状态
  • 线程常用方法
  • Thread相关类和示例

线程状态

  • 新建状态(New):新建线程对象
  • 就绪状态(Runnable) 调用start()方法
  • 运行状态(Running) 获得cpu的执行权限
  • (有人将阻塞分为三种,等待阻塞、同步阻塞和其他阻塞;个人觉得不利于理解线程的状态)
  • BLOCKED/WAITING/TIMED_WAITING
  • BLOCKED: 同步代码块/等待lock
  • WAITING:无限等待唤醒、没有超时时间的wait和join方法/locksupport.park()
  • TIMED_WAITING: 有时限的等待、包括sleep、wait(ts)、join(ts)、locksupport.parkNanos/parkUntil
  • 死亡状态(Dead) 线程执行完成或者异常退出
public enum State {
    /**
     * Thread state for a thread which has not yet started.
     */
    NEW,

    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     */
    RUNNABLE,

    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * {@link Object#wait() Object.wait}.
     */
    BLOCKED,

    /**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * following methods:
     * <ul>
     *   <li>{@link Object#wait() Object.wait} with no timeout</li>
     *   <li>{@link #join() Thread.join} with no timeout</li>
     *   <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     *
     * <p>A thread in the waiting state is waiting for another thread to
     * perform a particular action.
     *
     * For example, a thread that has called <tt>Object.wait()</tt>
     * on an object is waiting for another thread to call
     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
     * that object. A thread that has called <tt>Thread.join()</tt>
     * is waiting for a specified thread to terminate.
     */
    WAITING,

    /**
     * Thread state for a waiting thread with a specified waiting time.
     * A thread is in the timed waiting state due to calling one of
     * the following methods with a specified positive waiting time:
     * <ul>
     *   <li>{@link #sleep Thread.sleep}</li>
     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
     *   <li>{@link #join(long) Thread.join} with timeout</li>
     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
     * </ul>
     */
    TIMED_WAITING,

    /**
     * Thread state for a terminated thread.
     * The thread has completed execution.
     */
    TERMINATED;
}

线程常用方法 

// 睡眠,不释放控制权
TimeUnit.MINUTES.sleep(2);
//isAlive():线程处于“新建”状态时,线程调用isAlive()方法返回false。
//在线程的run()方法结束之前,即没有进入死亡状态之前,线程调用isAlive()方法返回true.
// yield():调用此方法的线程释放当前cpu的执行权、回到就绪状态.
// join():在A线程中调用B线程join()方法,表示当执行到此方法时,直到B线程执行完毕

//(过期)suspend()和resume() 暂停和重新开始,释放cpu执行权不释放锁;stop 已过期
//暂停和重开容易造成死锁,Stop无法释放资源

//wait() 和 notify() 等待和唤醒,释放cpu执行权和锁,Object方法
//wait/notify必须在同步代码块中执行,用于生成monitorenter 和 monitorexit指令
//同步块对象锁和执行wait的对象必须是同一个(否则IllegalMonitorStateException)
//监视器和对象锁(深入理解jvm)通俗地讲就是只有获取对obj的锁定之后才能用后面代码块中的代码访问obj资源,否则就无法访问obj也无法执行后面的代码,只能让线程停滞在那里等待其它线程解除对obj的锁定;

//interrupt 中断sleep、join和wait三者之一的阻塞继续执行。设置中断标志位为true;线程还是会执行完
//提前结束等待(抛出对应的中断异常InterruptedException: sleep interrupted)
//并不真正中断正在运行的线程,而只是发出中断请求,由线程在下一个合适的时刻中断自己。中断是取消线程最合理的方式。

Thread相关类和示例

Runnable、Callable、Future、FutureTask

继承Thread就不多说了,用的比较少;Runnable看上面的例子

Callable和Runnable差不多,不过实现方法时call,而且有返回值,不能交给Thread来包装运行

@Slf4j
public class RunnableDemo implements Runnable{

    @Override
    public void run() {
        log.info("-------10秒后大军来袭-----");
        synchronized (this){
            try {
                this.wait(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        log.info("-------keep going-----");
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new RunnableDemo());
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
@Slf4j
public class CallableDemo implements  Callable{

    String callName;

    public CallableDemo(String callName) {
        this.callName = callName;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建一个线程池
        ExecutorService pool = Executors.newFixedThreadPool(2);
        //创建两个有返回值的任务
        Callable c1 = new CallableDemo("A");
        Callable c2 = new CallableDemo("B");

        //执行任务并获取Future对象
        Future f1 = pool.submit(c1);
        Future f2 = pool.submit(c2);
        //从Future对象上获取任务的返回值,并输出到控制台
        log.info(">>>"+ f1.get().toString());
        log.info(">>>"+ f2.get().toString());
        //关闭线程池
        pool.shutdown();
    }

    @Override
    public Object call() throws Exception {
        log.info("-----执行call方法------");
        return  callName + ":success";
    }
}

Future是线程池的结果(泛型)类,在线程池Executor通过submit返回结果是Future;

用来查询Runnable或者Callable任务的执行情况,isDone,get等

FutureTask是一个类实现了RunnableFuture<V>,而RunnableFuture实现了Runnbale又实现了Futrue<V>这两个接口,另外它还能包装Runnale和Callable(通过适配器适配);

于是FutureTask既可以通过Thread包装来运行又可以交给ExecuteService来运行。

@Slf4j
public class FutureTaskDemo  {

    public static void main(String[] args) {
        CallableDemo callableDemo = new CallableDemo("测试futureTask");
        FutureTask futureTask1 = new FutureTask(callableDemo);
        futureTask1.run(); //同步

        RunnableDemo runnableDemo = new RunnableDemo();
        FutureTask futureTask2 = new FutureTask(runnableDemo, Future.class);
        Thread thread = new Thread(futureTask2);
        thread.start();//异步
        log.info("-----主线程结束----");
    }

}

补充一下:

从Future的实现子类FutureTask针对cancel()方法的实现中可以看出,cancel()方法取消线程的方法是调用interrupt()方法尝试中断线程。只会去设置中断位。

发布了62 篇原创文章 · 获赞 33 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/Zzhou1990/article/details/95617063
今日推荐