创建线程的几种方式
- 继承Thread 类
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("This is MyThread");
}
}
2.实现Runnable接口
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("This is MyRunnable");
}
}
3.实现Callable接口
public class MyCallable implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("This is callable");
return "OK";
}
}
启动线程的几种方式
public static void main(String[] args) {
/* 继承Thread的方法直接调用start()*/
new MyThread().start();
/* 实现Runnable接口的方法 通过new Thread() 方法传入并调用start()方法*/
new Thread(new MyRunnable()).start();
/* 实现Callable接口的方法 通过 Thread() 方法 传入FutureTask方法进行调用 */
new Thread(new FutureTask<String>(new Mycall())).start();
/* 通过lambda表达式调用*/
new Thread(()-> System.out.println("hello Lambda!")).start();
/* 通过线程池进行调用*/
ExecutorService service = Executors.newCachedThreadPool();
service.execute(()->{
System.out.println("hello ThreadPool");
});
}
线程的生命周期
- NEW 相当于new了个对象
- RUNNABLE 当线程调用了start方法后线程进入到Runnable状态,等待cpu分配资源。
- RUNNING CPU通过调度算法轮询到线程执行,此时Runnable状态的线程将进入到Running状态,并执行程序。
- BLOCKED 调用了sleep或者wait方法而加入到waitSet只能够,进行某个阻塞的IO操作,获取某个锁资源,加入到锁队列。
- TERMINATED 线程的最终状态。1线程允许正常结束、2线程允许出错意外退出、JVM Crash,导致所有的线程都结束。
线程的不同状态
当我们new出来一个线程时,此时线程还没有正式运行,也就是说线程处于新建状态。
当线程调用 start() 方法时,他会被线程调度器来执行,也就是交付给操作系统来执行,操作系统执行这个线程的整个状态是 Runnable状态,而 Runnable状态中有两个状态,一个是 Ready就绪状态和 Running运行状态。就绪状态就是将线程扔到cpu等待队列中去等待cpu运行,等真正到cpu上运行时才算是进入到运行状态。
如果线程正常执行就会进入 Teminated状态。
在 Runnable这个状态里面还有其他一些状态的改变 TimeWaiting等待、 Waiting等待和 Blocked阻塞状态,获得锁的时候是就绪状态运行。在运行的时候如果调用了 wait()、 join()、 LockSupport.park() 进入 Waiting 状态,调用 notify()、 notifyAll()、 LockSupport.unpark() 就又回到了 Running 状态。TimeWaiting按照时间等待,等时间结束自己就回到 Runable 状态。