Java线程.

来源:互联网 发布:阿里国际站关键词优化 编辑:程序博客网 时间:2024/05/10 13:26

Java 线程

基本概念

  1. 线程
    线程是程序执行的最小单元, 一个标准的线程由以下部分组成:

    • 线程ID
    • 当前指令指针(PC)
    • 寄存器集合
    • 堆栈

    线程是进程中的一个实体, 是被系统独立调度和分派的基本单位, 线程不拥有系统资源, 只拥有运行中必须的资源, 但是它可以与同一进程中的其他线程共享进程所拥有的全部资源.

  2. 进程
    进程是系统进行资源分配和调度的基本单位. 进程是线程的容器. 进程由以下部分组成:

    • 程序段(存储处理器执行的代码)
    • 数据段(存储变量和进程执行期间使用的动态分配的内存)
    • 进程控制块(存储着活动过程调用的指令和本地变量)

    进程具有以下特征:

    • 动态性: 进程的实质是程序在多道程序系统中的一次执行过程, 进程是动态产生, 动态消亡的;
    • 并发性: 任何进程都可以和其他进程并发执行;
    • 异步性: 由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进;
    • 结构特征:进程由程序、数据和进程控制块三部分组成。

线程的状态

  • 创建线程(New) (继承Thread类, 实现Runnable接口, )
  • 就绪状态(Runnable) (调用线程对象的start()方法)
  • 运行状态(Running) (就绪线程获得CPU资源, 执行程序代码)
  • 阻塞状态(Blocked) (线程因某些原因放弃CPU使用权, 暂停运行)
    • 等待阻塞: 运行的线程执行wait()方法, JVM将线程放入等待池中
    • 同步阻塞: 运行的线程在获取对象的同步锁时, 如果同步锁被占用, 则JVM会把线程放入锁池中
    • 其他阻塞: 运行线程执行sleep()join()方法, 或者发出I/O请求, JVM会把该线程置为阻塞状态.当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态
  • 死亡状态(Dead) 线程执行完了或者因异常退出了run()方法, 该线程结束生命周期

进程的状态

  • 创建进程(New) 创建进程分为以下两步完成:
    • 为一个新进程创建PCB, 并填写必要的管理信息
    • 把该进程转入就绪状态并插入就绪队列之中
  • 就绪状态(Ready) 进程已经分配到除了CPU以外的必要资源, 只要在获得CPU进程就转到执行状态
  • 执行状态(Running) 进程分配到CPU, 执行程序
  • 阻塞状态(Blocked) 进程因为某些原因无法继续执行, 放弃对CPU的使用权
  • 挂起状态 引起挂起状态的原因有以下几点:
    • 终端用户的请求
    • 父进程请求
    • 负荷调节的需要
    • 操作系统的需要
  • 终止状态(Dead) 等待操作系统进行善后处理,然后将其PCB清零,并将PCB空间返还系统。当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结,它将进入终止状态。进入终止态的进程以后不能再执行,但在操作系统中依然保留一个记录,其中保存状态码和一些计时统计数据,供其它进程收集。一旦其它进程完成了对终止状态进程的信息提取之后,操作系统将删除该进程。

示例代码

创建线程

  1. 继承Thread类
    1. 定义Thread的子类, 重写run()方法
    2. 创建Thread子类的实例
    3. 调用Thread子类的实例的start()方法, 启动线程
    public class Thread001 {        public static void main(String []args) {            System.out.println("main thread name is:" + Thread.currentThread().getName());            DemoExtendsThread thread1 = new DemoExtendsThread("DemoExtendsThread");            thread1.start();        }    }    class DemoExtendsThread extends Thread {        public DemoExtendsThread(String name) {            super(name);        }        @Override        public void run() {            System.out.println("DemoExtendsThread thread name is:" + Thread.currentThread().getName());            System.out.println("created thread by extend Thread class");        }    }
  1. 实现Runnable接口
    1. 定义实现Runnable接口的实现类, 重写run()方法
    2. 创建Runnable实现类的实例
    3. 创建Thread类的实例, 并将Runnable实现类的实例作为参数传递给Thread类的构造函数
    4. 调用Thread类的实例的run()方法
    public class Thread002 {        public static void main(String []args) {            DemoImplementRunable thread2 = new DemoImplementRunable();            Thread thread = new Thread(thread2,"DemoImplementRunable");            thread.start();        }    }    class DemoImplementRunable implements Runnable {        @Override        public void run() {            System.out.println("DemoImplementRunable thread name is:" + Thread.currentThread().getName());            System.out.println("create thread by implements Runnable");        }    }
  1. 通过Callable和Future创建线程
    1. 定义实现Callable接口的类, Callable可以传递一个泛型, 即返回值的类型
    2. 创建Callable实现类的实例, 创建FutureTask类实例, 并将Callable实现类的实例传递给FutureTask类实例
    3. 创建Thread类的实例, 将FutureTask类实例传递给Thread实例
    4. 调用Thread实例的start()方法启动线程
    public class Thread003 {        public static void main(String []args) {            System.out.println("main thread name is:" + Thread.currentThread().getName());            DemoImplementCallable thread3 = new DemoImplementCallable();            FutureTask<Integer> futureTask = new FutureTask<>(thread3);            new Thread(futureTask, "DemoImplementCallable").start();            try {                System.out.println("子线程返回的值:" + futureTask.get());            } catch (InterruptedException e) {                e.printStackTrace();            } catch (ExecutionException e) {                e.printStackTrace();            }        }    }    class DemoImplementCallable implements Callable<Integer> {        @Override        public Integer call() throws Exception {            System.out.println("DemoImplementCallable thread name is:" + Thread.currentThread().getName());            System.out.println("create thread by implements Callable");            return 1;        }    }

run()与start()的区别

  1. 在程序中直接调用run()方法时, run()方法中的代码并不会在新的线程执行, 而是在当前线程执行.
  2. 调用start()方法时才会创建新的线程, run()方法中的代码才会在新的线程中执行.
public class Thread004 {    public static void main(String []args) throws InterruptedException {        System.out.println("main method is starting!");        System.out.println("main thread name is:" + Thread.currentThread().getName());        ThreadRunAndStart threadRunAndStart = new ThreadRunAndStart();        // 1. 直接调用run()方法        threadRunAndStart.run();        // 2. 调用Thread的start()方法        new Thread(threadRunAndStart, "ThreadRunAndStart").start();        System.out.println("main method is over!");    }}class ThreadRunAndStart implements Runnable {    @Override    public void run() {        for (int i=0; i<100; i++) {            System.out.println("run in " + Thread.currentThread().getName() + ", i=" + i);        }    }}
0 0
原创粉丝点击