Java线程

六种线程状态:

NEW (初始): 创建线程后, 还没开始工作运行, 就是NEW状态

RUNNABLE (运行): 运行中, 就是RUNNABLE (又可分成正在运行和即将开始运行)

TIMED_WAITING (超时等待)

WAITING (等待)

BLOCKED (阻塞): 都表示排队等待

TERMINATED (终止): 表示工作完成运行结束

Java线程_第1张图片

图中的箭头清晰的表示了几种可以来回切换的状态, 如WAITING和RUNNABLE之间可以通过wait和notify等切换

没有双向箭头的就表示不能来回切换!!

比如RUNNABLE和TERMINATER就不能切换, 即同一个线程运行结束后不能重新再次运行(不能多次start), 否则编译器会抛出IllegalThreadStateException

假如想实现线程的内容多执行, 可以考虑重复创建Thread,传入相同的Runnable对象

线程的创建

  1. 继承Thread, 重写run方法
  2. 使用Runnable, 重写run方法
  3. 对Thread对象的实例使用匿名内部类, 继承Thread
  4. 对Thread对象的实例使用匿名内部类, 实现Runnable
  5. 对Thread对象的实例使用匿名内部类, 使用lambda表达式

p.s. run方法的调用不会创建新的线程, 只有调用了start方法才会创建新的线程并且在新线程中自动开始执行run方法, 如:

public static void main(String[] args) {
    Thread thread = new Thread(() -> {
        System.out.println("继承Thread, 使用lambda表达式重写了run方法");
    });
    thread.start();
    thread.run();
}

调用start就创建了新线程thread, 并且在thread中执行run方法

调用run没有创建新线程, 只是在main主线程中执行了thread中重写的run方法

线程中断和线程等待

中断

线程开启之后是不会自动停止的, 只要程序没有被中止, 或者没有人为设置中断, 就会一直执行下去.

中断线程步骤:

  1. 自己设置一个flg标志位变量(boolean)
  2. 用isInterrupted来判定标志位(线程中自带了一个标志位), 通过调用interrupt方法来触发中断(interrupt的作用是告诉线程要结束, 相当于flg变成true, 最后到底结束不结束还得看线程后续代码决定, 好像是要用到shutdown??)

p.s. 线程在RUNNABLE状态下, interrupt方法会设置标志位;

      线程在阻塞状态(sleep. wait), 则会抛出异常, interrupt方法先设置标志位, 然后被wait, sleep等阻塞方法清除标志位

等待

.join()

表示阻塞等待, 在A线程中调用B线程的join, 表示A等待B结束后再执行, 如:

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(() -> {});
    thread.start();
    thread.join();
    System.out.println("等thread结束我再打印o");
}

main线程中调用thread线程的join, 就是等thread执行完后再执行main中join后面的代码

.sleep()

调用后线程进入TIMED_WAITING状态, 并通过时间控制线程什么时候从回到RUNNABLE

.wait()

调用后线程进入BLOCKED状态, 通过notify/notifyAll唤醒线程

p.s. sleep和wait的区别

  1. sleep是Thread类的方法, wait是Object类的方法
  2. sleep可以在任何地方使用, wait必须在锁(synchronized修饰的代码块)里面使用
  3. wait调用后, 进入BLOCKED并且将锁进行释放!!!, sleep不涉及锁, 进入的是TIMED_WAITING状态. 其中锁进行释放指的是????

你可能感兴趣的:(JavaEE,java,面试,jvm)