java多线程编程基础一 基本概念
概念一:什么是任务?
在生活中,我们经常听到有人说:“小李,安排你一个任务,你过会把这个资料送到601办公室”。生活中的这个任务其实就是小李要干的一件事情,那么在并发程序设计中的任务的概念就和生活中一样。并发编程中的任务也是一件事情,这件事的呈现形式就是我们写的代码,这个代码的功能就是我们要干的一件事情。例如下面的一段代码:
public class Task implements Runnable { @Override public void run() { System.out.println(1+2); } }
上述这段代码要干的一件事情就是输出1+2的结果,这段代码就是描述了一件事情(一个任务)。
总之并发编程中任务的概念就是我们为了某个特定功能编写的代码。
“小李,安排你一个任务,你过会把这个资料送到601办公室”,在这个描述中,把资料送到601办公室是任务,那么去执行任务的是小李这个人。同样的,代码只是描述了一个任务,那么要完成这个任务也需要一个实体去执行。在并发编程中执行任务的实体就是线程或者进程。
概念二:什么是进程、什么是线程?
狭义定义:进程就是一段程序的执行过程。
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
进程与线程在操作系统中或者Linux系统编程中做区分意义还算大,如果放在java的并发编程中,意义不会很大,我们只要知道他们都是执行任务的实体就行。
概念三:什么是同步、什么是异步?
同步与异步是用来形容方法调用的。例如代码:
public static String A() { try { Thread.sleep(10000000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "张三"; } public static void B() { A(); }
在B方法中,调用了A方法。A方法要执行好久,而B方法要等着A方法执行完才会继续向下执行,那么这时候B调用A方法就属于同步调用。如果B方法不等A执行完就直接往下执行,那么这时候B对A的调用就是异步调用。
概念四:挂起、休眠、阻塞与非阻塞
挂起(Suspend):当线程被挂起的时候,其会失去CPU的使用时间,直到被其他线程(用户线程或调度线程)唤醒。
休眠(Sleep):同样是会失去CPU的使用时间,但是在过了指定的休眠时间之后,它会自动激活,无需唤醒(整个唤醒表面看是自动的,但实际上也得有守护线程去唤醒,只是不需编程者手动干预)。
阻塞(Block):在线程执行时,所需要的互斥资源不能得到,则线程被挂起,直到满足可操作的条件。
非阻塞(Block):在线程执行时,所需要的互斥资源不能得到,则线程不是被挂起等待,而是继续执行其余事情,待条件满足了之后,收到了通知(同样是守护线程去做)再执行。
而阻塞与非阻塞则是在互斥资源不能得到时的两种处理方式,不限于操作系统,当互斥资源申请不到时,要么挂起线程等待、要么继续执行其他操作,互斥资源被满足后再通知该线程重新请求。显然非阻塞的效率要高于阻塞,相应的实现的复杂度也要高一些。
概念五:临界区
临界区是用来代表一种公共的资源或者说共享数据。具体到java多线程中就是一段互斥代码。