[19/04/05-星期五] 多线程_Thread(线程、线条)、基本术语

一、基本概念

     多线程是Java语言的重要特性,大量应用于网络编程、服务器端程序的开发,最常见的UI界面底层原理、操作系统底层原理都大量使用了多线程。

     我们可以流畅的点击软件或者游戏中的各种按钮,其实,底层就是多线程的应用。UI界面的主线程绘制界面,

如果有一个耗时的操作发生则启动新的线程,完全不影响主线程的工作。当这个线程工作完毕后,再更新到主界面上。

     我们可以上百人、上千人、上万人同时访问某个网站,其实,也是基于网站服务器的多线程原理。如果没有多线程,服务器处理速度会极大降低。

【程序】

        “程序(Program)”是一个静态的概念,一般对应于操作系统中的一个可执行文件,比如:我们要启动酷狗听音乐,则对应酷狗的

可执行程序。当我们双击酷狗,则加载程序到内存中,开始执行该程序,于是产生了“进程”。

【进程】

         执行中的程序叫做进程(Process),是一个动态的概念。现代的操作系统都可以同时启动多个进程。比如:我们在用酷狗听音乐,也可以

使用eclipse写代码,也可以同时用浏览器查看网页。进程具有如下特点:

      1. 进程是程序的一次动态执行过程, 占用特定的地址空间。

      2. 每个进程由3部分组成:cpu、data、code。每个进程都是独立的,保有自己的cpu时间,代码和数据,即便用同一份程序产生好几个进程,

它们之间还是拥有自己的这3样东西,这样的缺点是:浪费内存,cpu的负担较重。

      3. 多任务(Multitasking)操作系统将CPU时间动态地划分给每个进程,操作系统同时执行多个进程,每个进程独立运行。以进程的观点来看,

它会以为自己独占CPU的使用权。

      4. 进程的查看

【线程】

        一个进程可以产生多个线程。同多个进程可以共享操作系统的某些资源一样,同一进程的多个线程也可以

共享此进程的某些资源(比如:代码、数据),所以线程又被称为轻量级进程(lightweight process)。

      1. 一个进程内部的一个执行单元,它是程序中的一个单一的顺序控制流程。

      2. 一个进程可拥有多个并行的(concurrent)线程。

      3. 一个进程中的多个线程共享相同的内存单元/内存地址空间,可以访问相同的变量和对象,而且它们从同一堆中分配对象并进行通信、数据交换和同步操作。

      4. 由于线程间的通信是在同一地址空间上进行的,所以不需要额外的通信机制,这就使得通信更简便而且信息传递的速度也更快。

      5. 线程的启动、中断、消亡,消耗的资源非常少。

线程和进程的区别:

     1. 每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。

      2. 线程可以看成是轻量级的进程,属于同一进程的线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。

      3. 线程和进程最根本的区别在于:进程是资源分配的单位,线程是调度和执行的单位。

      4. 多进程: 在操作系统中能同时运行多个任务(程序)。

      5. 多线程: 在同一应用程序中有多个顺序流同时执行。

      6. 线程是进程的一部分,所以线程有的时候被称为轻量级进程。

      7. 一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个线程,进程的执行过程不是一条线(线程)的,而是多条线(线程)共同完成的。

      8.  系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只

能共享资源。那就是说,除了CPU之外(线程在运行的时候要占用CPU资源),计算机内部的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。

进程与程序的区别:

    程序是一组指令的集合,它是静态的实体,没有执行的含义。而进程是一个动态的实体,有自己的生命周期。一般说来,一个进程肯定与一个程序相对应

并且只有一个,但是一个程序可以有多个进程,或者一个进程都没有。除此之外,进程还有并发性和交往性。简单地说,进程是程序的一部分,程序运行的时候

会产生进程。

二、Java中的线程

   继承Thread类实现多线程的步骤:

      1. 在Java中负责实现线程功能的类是java.lang.Thread 类。

      2. 可以通过创建 Thread的实例来创建新的线程。

      3. 每个线程都是通过某个特定的Thread对象所对应的方法run( )来完成其操作的,方法run( )称为线程体。

      4. 通过调用Thread类的start()方法来启动一个线程。

【代码示例】

【创建线程方法一】:继承Thread类+重写run()方法

 1 /**Thread 多线程 
 2  * 创建线程方式一: 
 3  * 1、创建:继承Thread类+重写run方法
 4  * 2、创建子类对象,启动线程
 5  * 
 6  */
 7 package cn.sxt.thread;
 8 
 9 
10 public class Test_0405_Thread extends Thread{
11     //重写run方法,【线程】入口点
12     public void run() {
13         for (int i = 0; i < 10; i++) {
14             System.out.println("一边听歌");
15             
16         }
17     }
18     public static void main(String[] args) {
19         //启动线程: 就是要创建一个子类对象
20         Test_0405_Thread thread=new Test_0405_Thread();//创建一个子类对象
21         thread.start();//启动线程,start()方法 开启一个线程,start(),自己会调run(),交给cpu去调用run()方法,但是main方法不会停止
22         //继续往下走由于cpu调用run方法回来时间不一定,输出结果可能是“听歌”与“敲代码”混合的,也可能先敲代码后听歌.
23         
24         //thread.run(); 若把上句换成这个直接调用run(),由于run()就是一普通方法,所以cpu肯定先调完run(),它再执行下边的语句
25         
26         for (int i = 0; i < 10; i++) {
27             System.out.println("一边敲代码");
28             
29         }
30         
31     }
32 
33 }
/**线程使用示例:从一个网站下载多张图片,同时下载
*
 * 
 */
package cn.sxt.thread;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import org.apache.commons.io.FileUtils;

public class Test_0405_WebDownload extends Thread {

    public static void main(String[] args) {
        ThreadDown t1=new ThreadDown("https://www.baidu.com/img/bd_logo1.png", "src_dest/baidu.jpg");
        ThreadDown t2=new ThreadDown("https://wx1.sinaimg.cn/mw690/775d10bdgy1g1u10vajc3j20k00d20u6.jpg", "src_dest/haimian.jpg");
        
        t1.start();
        t2.start();//2个线程独立,t1.start();先开始不一定它先结束
    }

}
//多线程下载类
class ThreadDown extends Thread{
    private String url;
    private String name;
    
    public ThreadDown(String url, String name) {
        super();
        this.url = url;
        this.name = name;
    }
    //下载方法 拷贝网络地址上"url"的一张图片到 文件"name"
    public void download(String url_1,String name_1) throws IOException {
        FileUtils.copyURLToFile(new URL(url_1), new File(name_1));        
    }

    public void run() {    
          try {
            download(url, name);
            System.out.println(name);//可以看出2张图片的下载并没有先后顺序t1.start();先开始但它不一定先下载完
        } catch (IOException e) {
            System.out.println("链接不合法!");
        }
        
    }
    
}

【创建线程方法二】 Runnable接口

/***
 * 创建线程方法二:实现Runnable接口(推荐),避免单继承的局限性,方便共享资源
 * 1、实现runnable接口+重写run
 * 2、启动 :创建实现类对象+创建代理类对象 +start
 */
package cn.sxt.thread;

public class Test_0405_Runnable implements Runnable {//1-1:实现接口
    public void run() {//1-2:重写run()方法
        System.out.println("听歌");

    }
    
    public static void main(String[] args) {
    /*  //2-1:创建实现类对象
        Test_0405_Runnable tRunnable=new Test_0405_Runnable();
        //2-2:创建代理类对象,丢入实现类对象tRunnable
        Thread thread=new Thread(tRunnable);
        //2-3:启动start
        thread.start(); */
        
        //合3为1, 创建匿名对象
        new Thread( new Test_0405_Runnable() ).start();//调用run方法去了,不知什么时候回来,主方法继续往下不等它
        
        System.out.println("敲代码");    
        
    }
}

 

猜你喜欢

转载自www.cnblogs.com/ID-qingxin/p/10665531.html
今日推荐