• 多线程的创建方式


    一:进程与线程       
           进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)
      线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)
      线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
      多进程是指操作系统能同时运行多个任务(程序)。
      多线程是指在同一程序中有多个顺序流在执行。
    2:实现多线程有三种方法:一种是继续Thread类,另外一种是实现Runable接口.第三种是实现Callable接口通过FutureTask包装器来创建Thread线程
    //继承Thread类
    public class MyThread extends Thread{ 
     public void run(){
      //重写run方法
      }
    }
    new MyThread().start();//创建并启动线程
    
    
    //实现Runnable接口
    public class MyThread2 implements Runnable { 
     public void run(){
      //重写run方法
      }
    }
     //创建并启动线程
        MyThread2 myThread=new MyThread2();
        Thread thread=new Thread(myThread);
        thread().start();
    
    
    //实现Callable接口,使用FutureTask包装
     FutureTask<String> ft = new FutureTask<String>(new Callable<String>() {
                
                 @Override
                 public String call() throws Exception {
                     System.out.println("new Thread 3");//输出:new Thread 3
                     return "aaaa";
                 }
             });
             
             Thread t3 = new Thread(ft);
             t3.start();
             String result = ft.get();//法会阻塞,直到子线程执行结束才返回
             System.out.println(result);//输出:aaaa
             
         }
    View Code

    直接调用线程的run方法时,并不是多线程,只是一个普通顺序方法。必须调用start方法才是多线程的调用方式

    3.区别

    实现Runnable和实现Callable接口的方式基本相同,不过是后者执行call()方法有返回值,前者线程执行体run()方法无返回值,因此可以把这两种方式归为一种这种方式与继承Thread类的方法之间的差别如下:

    <1、线程只是实现Runnable或实现Callable接口,还可以继承其他类。

    <2、这种方式下,多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形。

    <3、但是编程稍微复杂,如果需要访问当前线程,必须调用Thread.currentThread()方法。

    <4、继承Thread类的线程类不能再继承其他父类(Java单继承决定)。

    4.线程状态转换

    <1、新建状态(New):新创建了一个线程对象。
    <2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
    <3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
    <4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
    (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)
    (二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
    (三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)
    <5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    注:一般推荐采用实现接口的方式来创建多线程

    在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个jVM实际就是在操作系统中启动了一个进程。
     
  • 相关阅读:
    第二章 万变不离其踪--收割自己的深度图
    2.1 光照系统
    2.2 深度渲染机制
    2.3 来点实际--日照分析实现
    2.4 通视分析
    2.5 Cesium视域分析的实现
    2.6
    第三章 讲真,没几个搞得清楚的经纬度——GIS坐标
    3.1 地理坐标系统
    3.2 渲染坐标系统
  • 原文地址:https://www.cnblogs.com/nzxj/p/10465833.html
Copyright © 2020-2023  润新知