线程、多线程、线程池

来源:互联网 发布:杭州行知小学两个校区 编辑:程序博客网 时间:2024/05/01 11:59

· 线程

线程是操作系统能够进行运算调度的最小单位,线程被包含在进程中,一个进程至少包含一个线程,进程也可以并发的执行多个线程。


线程的生命周期:

新建状态(New) 新创建了一个线程,还没有调用.start()启动。

就绪状态(Runnable)调用.start()方法,启动了该线程,等待CPU的调度。

运行状态(Running)获取到了CPU使用权,执行代码。

阻塞状态(Blocked)因为某种原因暂停运行,直到再次进入就绪状态。

死亡状态(Dead)线程执行完run方法自然死亡,或者在出现异常而死亡。


线程的创建有两种方法:

1.继承Thread类

public class MyThread extends Thread {@Overridepublic void run() {//重写run方法//这里就是我们要在子线程中执行的操作}}
MyThread t = new MyThread();

2.实现Runnable接口

public static class MyRunnable implements Runnable {public void run(){//重写run方法//这里就是我们要在子线程中执行的操作}}
Thread t = new Thread(new MyRunnable());

创建了线程之后并没有直接启动,调用 t.start() 方法之后才真正启动了线程。
这里需要注意的是线程的run()方法, t.run()和t.start()方法都能调用到线程内部的run()方法,但是t.run()方法调用的run()方法并不是在新创建的线程里执行的,而是被创建新线程的线程给执行了。
public static void main(String[] args) {for(int i=0; i<10; i++){final int count = i; new Thread("Thread_" + count){public void run(){System.out.println(count + " " + Thread.currentThread().getName() + " is running");}}.run();}}
这里我在内部创建了10个线程,并且调用.run()方法,而不是.start()方法,所以打印出来的十个输出方法都是由main线程执行的。如果在这里调用.start()方法,就会输出每个线程的线程名,也就是各自执行的线程。

线程的创建顺序并不等于线程的执行顺序,线程的执行是无序的。
public static void main(String[] args) {System.out.println(Thread.currentThread().getName() + " is running");for(int i=0; i<10; i++){final int count = i; new Thread("Thread_" + count){public void run(){System.out.println(Thread.currentThread().getName() + " is running");}}.start();}}

我在创建线程的时候是有序的创建的,而在线程执行的时候从输出台的语句可以看到并不是有序的。



· 多线程

多线程顾名思义就是多个线程同时存在。

多线程的优点是能够适当提高程序的执行效率和CPU利用率内存利用率等。但是大量的线程会占据一定的内存空间,并且CPU的使用也会加大。

多个线程对同一个对象执行操作会产生一些的错误,比如对同一个文件进行读写,所以在需要进行这些操作的线程前加上synchronized关键字来确保同一时刻只有一个线程能进行操作。



· 线程池

不断的进行线程的创建会造成内存溢出,利用线程池来管理线程可以限制线程的数量,并且回收再利用。

线程池的顶级接口是 Executor,不过真正的线程池接口是 ExecutorService, ExecutorService 的默认实现是 ThreadPoolExecutor。

Executors 提供四种线程池:

(1)newCachedThreadPool可缓存线程池,线程数量过多就回收空闲线程

(2)newFixedThreadPool 固定大小线程池,限定最大并发线程数,超过这个限定值就在队列中等待

(3)newScheduledThreadPool 大小无限线程池,支持定时及周期性任务执行

(4)newSingleThreadExecutor 单线线程池,只有一个线程串行处理所有任务,如果线程一场结束,会产生一个新线程


向线程池提交任务

execute(),向线程池提交一个任务

submit(),向线程池提交一个任务,并且返回该任务的执行结果

关闭线程

shutdown():关闭线程池,等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
shutdownNow():立即关闭线程池,尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务


0 0