并发与并行,进程与线程不只是操做系统中及其重要的概念,也是并发编程入门 java
必需要理解的核心知识。 web
顺序编程:程序中的全部事物在任意时刻都只能执行一个步骤 编程
并发:在同一时间段内,须要处理多个任务,而在每一个时间点又只能处理一个,这就是并发。 安全
假设咱们要把多个任务分配给处理机,若是这台机器有多个处理器,显然能够同时执行这些任务,这就是并行。 多线程
不一样于并行,并发的目的旨在最大限度的提升程序在单处理器上的效率。前者是在物理上的同时发生,而并发是在逻辑上的同时发生。如图,若是要在同一个时间段内处理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多线程对于线程的建立有了初步的了解。在本系列的后续部分将会继续探讨并发编程中的细节。
若是以为本文对您有所帮助的话,就给俺点个赞吧~