进程:我们都知道计算机的核心是CPU,它承担了所有的计算任务;而操作系统是计算机的管理者,它负责任务的调度、资源的分配和管理,统领整个计算机硬件;应用程序则是具有某种功能的程序,程序是运行于操作系统之上的。
进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程序、数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;程序控制块(Program Control Block,简称PCB),包含进程的描述信息和控制信息,是进程存在的唯一标志。
进程具有的特征:
动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
并发性:任何进程都可以同其他进程一起并发执行;
独立性:进程是系统进行资源分配和调度的一个独立单位;
结构性:进程由程序、数据和进程控制块三部分组成。
线程:在早期的操作系统中并没有线程的概念,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。任务调度采用的是时间片轮转的抢占式调度方式,而进程是任务调度的最小单位,每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。
随着计算机的发展,对CPU的要求越来越高,进程之间的切换开销较大,已经无法满足越来越复杂的程序的要求了。于是就发明了线程,线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。
进程与线程的区别:
1. 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
2. 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
3. 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见;
4. 调度和切换:线程上下文切换比进程上下文切换要快得多。
进程与线程的联系:
i.线程依托与进程存在,多个线程共享进程的资源,os中任务调度的基本单位;
ii.启动,撤销一个进程的开销要比启动,撤销一个线程大得多;
iii.没有进程就没有线程,进程一旦终止,其内的线程全部撤销。
什么是高并发?
高并发就是同一时刻线程的访问量非常非常高
高并发带来的问题:服务器内存不够,无法处理新的请求。
多线程实现:
1.继承Thread类实现多线程
java.lang.Thread是线程操作的核心类,JDK1.0提供
新建一个线程最简单的方法是直接继承Thread类,而后覆写类中的run()方法(相当于主方法)
注:无论哪种方式实现多线程,线程启动一律调用Thread类提供的start()方法。
start()方法解析:
class MyThread extends Thread { // 线程主体类
private String result ;
public MyThread(String result ) {
this.result = result ; }
public void run() { // 所有线程从此处开始执行
for (int i = 0; i < 10 ; i++) {
System.out.println(this.result +",i = " + i);
}
}
}
public class Test{
public static void main(String[] args) {
MyThread myThread1 = new MyThread("thread1") ;
MyThread myThread2 = new MyThread("thread2") ;
MyThread myThread3 = new MyThread("thread3") ;
myThread1.start();
myThread2.start();
myThread3.start();
} }
i.首先检查线程状态是否为0(线程默认状态为0表示未启动),如果线程已经启动再次调用start()方法会抛出异常
ii.一个线程start()只能调用一次,其次每一个线程对象只能够启动一次
iii.JVM调用start0方法进行资源分配与系统调度,准备好资源启动线程后回调run()来执行线程的具体任务
2.Runnable接口来实现多线程
class MyThread implements Runnable { // 线程主体类
private String result ;
public MyThread(String result ) {
this.result = result ; }
public void run() { // 所有线程从此处开始执行
for (int i = 0; i < 10 ; i++) {
System.out.println(this.result +",i = " + i);
}
} }
public class Test{
public static void main(String[] args) {
MyThread myThread1 = new MyThread("thread1") ;
MyThread myThread2 = new MyThread("thread2") ;
MyThread myThread3 = new MyThread("thread3") ;
new Thread(myThread1).start();
new Thread(myThread2).start();
new Thread(myThread3).start();
}
}
i.java中多线程的处理就是一个典型的代理模式。其中Thread类完成资源调度,系统分配辅助线程业务类;自定义的线程类负责真实业务实现
ii.使用Runnable接口实现的多线程程序类可以更好的描述资源共享。
Thread与Runnable的区别:
首先从使用形式来讲,明显使用Runnable实现多线程要比继承Thread类要好,因为可以避免单继承局限。
使用Runnable实现的多线程的程序类可以更好的描述出程序共享的概念。
3.Callable<V>实现多接口:
juc:高并发程序包
java.util.concurrrent.Callable<V>:
V Call()throws Exception: 线程执行后有返回值V
V get() throws InterruptedException,ExecutionException:
取得Callable接口call()方法
注:1.当线程需要返回值时只能采用Callable接口实现多线程。
2. 多线程的启动永远都是Thread类的start()方法
多线程常用的操作方法
1.线程的命名与取得
i.通过构造方法将线程命名:
public Thread(String name)
public Thread(Runnable target ,String name)
ii.设置线程名称:
public final synchronized void setName(String name)
iii.取得线程名称:
public final String getName()
iV.取得当前正在执行的线程对象
publica static native Thread currentThread()
注意:JAVA中的main方法实际上是一个主线程(main)
2.线程休眠(sleep方法)
线程休眠:指的是让线程暂缓执行,等到了预计时间在回复执行
线程休眠会立即交出CPU,让CPU去执行其他任务。线程休眠不会释放对象锁,也就是说如果当前线程保持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。
3.线程让步(yield)
暂停当前正在执行的线程对象,并执行其他线程
yield()会让当前线程交出CPU,但是不一定立即交出,yield()交出CPU以后只能让拥有相同优先级的
线程有获取CPU的机会。yeild()不会释放对象锁
4.join()方法
等待该线程终止,如果在主线程中调用该方法会让主线程休眠,让调用该方法的线程先执行完毕后在恢复执行主线程。
注:join()只是对Object类wait()做了一层包装
5.线程停止
i.手工设置标记位,让线程在满足条件后退出
ii. 使用stop()方法强制让线程退出,但是该方法不安全已经被废弃了
iii. 使用Thread类提供的interrupt()中断线程
注:interrupt()方法只是将线程的状态改为中断状态而已,他不会中断一个正在执行的线程。如果线程调用了外套wait(),sleep(),join() 进入阻塞状态,调用该线程的interrupt()会抛出InterruptedException(受查异常并且将线程interrupt重置为false。
6.线程的优先级[1-10]
线程的优先级是指,优先级越高越有可能先执行而已,仅仅是有可能而已。
设置优先级:
public final void setPriority(int newPriority)
取得优先级
public final int getPriority()
thread.MAX_PRIORITY=10
thread.NORM_PRIORITY=5
thread.MIN_PRIORITY=1
注:主方法只是一个中等线程
线程是有继承性的:优先级可以继承
在A线程中启动B,则A和B优先级一样、