zoukankan      html  css  js  c++  java
  • 进程和线程

    进程和线程

    并发与并行,进程与线程不仅是操作系统中及其重要的概念,也是并发编程入门

    必须要理解的核心知识。

    1. 什么是并发?并发与并行的区别

    顺序编程:程序中的所有事物在任意时刻都只能执行一个步骤

    并发:在同一时间段内,需要处理多个任务,而在每个时间点又只能处理一个,这就是并发。

    假设我们要把多个任务分配给处理机,如果这台机器有多个处理器,显然可以同时执行这些任务,这就是并行

    不同于并行,并发的目的旨在最大限度的提高程序在单处理器上的效率。前者是在物理上的同时发生,而并发是在逻辑上的同时发生。如图,如果要在同一个时间段内处理task1, task2,需要在任务之间来回切换,完成并发执行

    图:一个简单并发的例子

        2.  Java的多线程和并发性

    Java是一种多线程语言,并发是Java非常重要的高级特性之一。对于分布式系统甚至于web系统的开发者来说,学会高效的并发编程至关重要。例如,web系统是Java的常见应用之一,最基本的java web库类 Servlet就具备天生的多线程特性,图形用户界面类似于Swing和SWT也具备线程安全的机制。如果你不了解并发,你很难很好的使用好这些工具。

        3.  进程和线程

    进程可以定义为一个执行中的程序的实例,进程拥有自己的地址空间,以及用来记录进程的进程控制块(PCB)。想到实现并发,人们最先想到的便是通过进程。在多任务操作系统中,CPU会周期性地从一个进程切换到另一个进程。这种实现方式非常理想化,由于不同进程处于不同的地址空间,彼此之间不会干涉,这使得实现起来更为容易。

    可惜的是,虽然具有以上优点,但由于进程通常都会有开销和数量的限制,想要使用进程来并发编程显然不够经济。

    图:进程的开销( 任务管理器)

    函数型语言可以将并发任务彼此隔离,这种专门的并发语言为处理大量并发任务提供了方便。

    线程是在单一进程中创建的任务,线程与线程之间共享进程的地址空间和内存资源,Java的并发就是在顺序语言的基础上引入线程机制,通过多线程 之间的协作来实现并发。

    多线程并发的好处是可以共享资源,开销较小,然而同时也使得系统的复杂性增加。不过与程序设计的方便性,资源的负载均衡实现相比,复杂性代价也变得微不足道了。

        4.  线程的创建

    Java中创建线程,经常用到java.lang.Thread类,如下创建一个线程:

    Thread thread  = new Thread();

    调用start()方法启动线程

    thread.start();

    由于我们没有继承Thread类,重载Thread的run()方法,所以在start()之后线程没有任何动作。

    要想让线程执行我们想要它完成的任务,还需要创建Thread的子类来重载run()方法。

        5.  创建Thread子类

    举个栗子

    复制代码
    public class MyThread extends Thread {
    
        public void run(){
    
            System.out.println("ACFLOOD!");
    
        }
    
    }
    复制代码

    通过如下代码来运行MyThread

    MyThread myThread = new MyThread();
    
    myThread.start();

        6.  实现Runnable接口

    我们还可以通过实现Runnable接口来实现run()方法,你可能会问,Runnable和Thread的区别是什么? 其实,在Java的多线程机制中,Runnable的实现就相当于一个Task,也就是我们想让线程完成的任务。Thread的目的是用来驱动这些任务,我们想要执行Task,只需要把Runnable的实例放入Thread中。比如下面的倒计时任务LiftOff

    复制代码
    public class LiftOff implements Runnable {
    
      protected int countDown = 10; //Default
    
      private static int taskCount = 0;
    
      private final int id = taskCount++;
    
     
    
      public LiftOff(){}
    
      public LiftOff(int countDown){
    
          this.countDown = countDown;
    
      }
    
     
    
      public String status() {
    
          return "#" + id  + "(" + (countDown > 0 ? countDown : "LiftOff!")+").";
    
      }
    
     
    
      public void run(){
    
          while(countDown-- > 0){
    
            System.out.print(status());
    
            Thread.yield(); //对线程调度的建议
    
        }
    
      }
    
    }
    复制代码

    我们可以直接调用run()方法来执行

    复制代码
    public class MainThread {
    
        public static void main(String[] args){
    
            LiftOff launch = new LiftOff();
    
            laucn.run();
    
        }
    
    }
    复制代码

    更好的办法是交给Thread类来调度

    复制代码
    public class BasicThreads{
    
         Thread t = new Thread(new LiftOff());
    
         t.start();
    
         System.out.println("Waiting for LiftOff");       
    
    }
    复制代码

    在这个例子中,start()方法执行之后返回,之后输出main()主线程中的waiting for liftoff,run()在另一个线程最后执行完成。

        7.  总结

    通过本文的学习,相信读者对并发的基本概念,并发基本的实现原理,以及java多线程对于线程的创建有了初步的了解。在本系列的后续部分将会继续探讨并发编程中的细节。

  • 相关阅读:
    298. Binary Tree Longest Consecutive Sequence
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    163. Missing Ranges
    336. Palindrome Pairs
    727. Minimum Window Subsequence
    211. Add and Search Word
    年底购物狂欢,移动支付安全不容忽视
    成为程序员前需要做的10件事
    全球首推iOS应用防破解技术!
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5544347.html
Copyright © 2011-2022 走看看