一.线程
1.什么是线程:
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个进程至少包含一个线程,也可以多个,线程属于进程。
2.Java中线程经历的四个过程:
(1)创建:
创建一个Java线程常见的有两种方式:继承Thread类和实现Runnable接口这两种方式。
(2)执行:
线程创建后仅仅占有了内存资源,在JVM管理的线程中还没有该线程,该线程必须调用start方法通知JVM,这样JVM就会知道又有一个新的线程排队等候了。如果当前线程轮到了CPU的使用权限的话,当前线程就会继续执行。
(3)中断:
a.JVM将CPU的使用权限从当前线程切换到其它线程,使本线程让出CPU的使用权限而处于中断状态。
b.线程在执行过程中调用了sleep方法,使当前线程处于休眠状态。
c.线程在执行的过程中调用wait方法
d.线程在使用cpu资源期间,执行了某个操作而进如阻塞状态。
(4)死亡
死亡的线程不在具有执行能力。线程死亡的原因有二:
a.线程正常运行结束而引起的死亡,即run方法执行完毕。
b.线程被提前强制终止。
3.Thread类:
3.1构造方法:
构造方法摘要 | |
分配新的 | |
分配新的 | |
分配新的 | |
分配新的 | |
分配新的 | |
分配新的 | |
分配新的 | |
分配新的 |
3.2常用方法:
方法摘要 | |
|
返回该线程的标识符。 |
|
返回该线程的名称。 |
|
返回线程的优先级。 |
|
中断线程。 |
|
测试当前线程是否已经中断。 |
|
测试线程是否处于活动状态。 |
|
测试该线程是否为守护线程。 |
|
等待该线程终止。 |
|
等待该线程终止的时间最长为 |
|
等待该线程终止的时间最长为 |
|
如果该线程是使用独立的 |
|
改变线程名称,使之与参数 |
|
更改线程的优先级。 |
|
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 |
|
在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 |
|
使该线程开始执行;Java 虚拟机调用该线程的 |
3.3相关方法使用:
(1)继承实现Thread类:
1 package com.swpu.thread;
2 class MyThread extends Thread{
3 public MyThread(String name){
4 super(name);
5 }
6 public void run(){
7 for(int i=0;i<10;i++){
8 System.out.println(getName()+"正在运行"+(i+1));
9 }
10
11 }
12 }
13 public class ThreadTest {
14
15 public static void main(String[] args) {
16 // TODO Auto-generated method stub
17 MyThread mythread1=new MyThread("线程1");
18 MyThread mythread2=new MyThread("线程2");
19 mythread1.start();
20 mythread2.start();
21
22
23
24 }
25
26 }
View Code
(2)实现Runnable接口:
为什么要实现Runnable接口:Java不支持多继承了不打算重写Thread类的其他方法。
1 package com.swpu.thread;
2
3 class PrintRunnable implements Runnable {
4 @Override
5 public void run() {
6 // TODO Auto-generated method stub
7 for (int i = 1; i < 10; i++) {
8 System.out.println(Thread.currentThread().getName() + "正在运行"+(i++));
9 }
10 }
11 }
12
13 public class ThreadTest {
14
15 public static void main(String[] args) {
16 // TODO Auto-generated method stub
17 //如果都是使用的pr1,那就相当于资源共享
18 PrintRunnable pr1 = new PrintRunnable();
19 Thread th1 = new Thread(pr1);
20 PrintRunnable pr2 = new PrintRunnable();
21 Thread th2 = new Thread(pr2);
22 th1.start();
23 th2.start();
24
25 }
26
27 }
View Code
3.4线程的状态:
3.5正在运行状态---->阻塞状态相关方法使用:
(1)sleep():
在指定的毫秒数内让正在执行的线程休眠(暂停执行),参数是休眠的时间(毫秒)。
使用场景:定期刷新某项东西,计时间等
1 package com.swpu.thread;
2
3 class PrintRunnable implements Runnable {
4 @Override
5 public void run() {
6 // TODO Auto-generated method stub
7 for (int i = 1; i < 10;) {
8 System.out.println(Thread.currentThread().getName() + "正在运行" + (i++));
9 //需要捕获异常(运行时退出)
10 try {
11 //休眠时间结束后,线程不会立即变成执行状态,而是变成可执行状态,需要获取CPU使用权才能变成执行状态
12 //因此时间需要多花一点
13 Thread.sleep(1000);
14 } catch (InterruptedException e) {
15 e.printStackTrace();
16 }
17 }
18 }
19 }
20
21 public class ThreadTest {
22
23 public static void main(String[] args) {
24 // TODO Auto-generated method stub
25 // 如果都是使用的pr1,那就相当于资源共享
26 PrintRunnable pr1 = new PrintRunnable();
27 Thread th1 = new Thread(pr1);
28 PrintRunnable pr2 = new PrintRunnable();
29 Thread th2 = new Thread(pr2);
30 th1.start();
31 th2.start();
32
33 }
34
35 }
View Code
(2)join():
等待该方法的线程结束后才能执行。也有个参数为毫秒,等待线程终止的最长时间为多少毫秒(即在该线程执行的最长时间,无论线程是否结束都会执行其他线程)。
1 package com.swpu;
2
3 class MyThread extends Thread {
4 public void run() {
5 for (int i = 0; i < 10; i++) {
6 System.out.println(getName() + "执行第" + (i + 1));
7 }
8 }
9
10 }
11
12 public class ThreadTest {
13
14 public static void main(String[] args) {
15 // TODO Auto-generated method stub
16 MyThread mythread = new MyThread();
17 mythread.start();
18 try{
19 //抢占资源,会等待Thread-0运行完成后,其他线程才能执行
20 mythread.join();
21 }
22 catch(InterruptedException e){
23 e.printStackTrace();
24 }
25 for(int i=0;i<10;i++){
26 System.out.println("主线程运行第"+(i+1));
27 }
28
29
30 }
31
32 }
View Code
3.6线程优先级:(优先级的设置与操作系统及工作环境都有关)
Java线程类提供10个优先级;
优先级可以用整个整数1-10表示,超过范围会抛出异常;
主线程默认优先级为5。
优先级常量:MAX_PRIORITY:线程的最高优先级10,MIN_PRIORITY:线程的最低优先级1,NORM_PRIORITY:线程的默认优先级5(主线程为5)
优先级方法:getPriority()获得优先级,setPriority()设置优先级、
1 package com.swpu;
2
3 class MyThread extends Thread {
4 public void run() {
5 for(int i=0;i<50;i++){
6 System.out.println(getName()+"运行完成"+(i+1));
7 }
8 }
9
10 }
11
12 public class ThreadTest {
13
14 public static void main(String[] args) {
15 // TODO Auto-generated method stub
16 int mainPriority=Thread.currentThread().getPriority();
17 System.out.println("主线程优先级为:"+mainPriority);
18 MyThread mythread1 = new MyThread();
19 MyThread mythread2 = new MyThread();
20 //设置两个线程的优先级
21 mythread1.setPriority(Thread.MAX_PRIORITY);
22 mythread2.setPriority(Thread.MIN_PRIORITY);
23 mythread1.start();
24 mythread2.start();
25
26
27
28 }
29
30 }
View Code
4.线程中的问题及线程同步:
各个线程是通过竞争CPU时间而获得运行时间的;
各CPU什么时候得到CPU时间,占用多久,是不可预测的;
一个正在运行的线程在什么地方被暂停是不确定的。
线程同步:synchronized关键字用在成员方法,静态方法,语句块。【防止执行过程中语句未执行完整跳到另一个线程,使取得的数据有误差】
5.线程间通信:
wait():在其他线程调用此对象的 notify()
方法或 notifyAll()
方法前,导致当前线程等待;
notify(): 唤醒在此对象监视器上等待的单个线程;
notifyAll(): 唤醒在此对象监视器上等待的所有线程。
例:
Queue:
1 package com.swpu.queue;
2
3 public class Queue {
4 private int n;
5 boolean flag=false;
6 public synchronized int get() {
7 if(!flag){
8 try{
9 wait();
10 }
11 catch(InterruptedException e){
12 e.printStackTrace();
13 }
14 }
15 System.out.println("获取:"+n);
16 flag=false;//消费完毕
17 //唤醒所有线程,notify()随机唤醒一个
18 notifyAll();
19 return n;
20 }
21
22 public synchronized void set(int n) {
23 if(flag){
24 try{
25 wait();
26 }
27 catch(InterruptedException e){
28 e.printStackTrace();
29 }
30 }
31 System.out.println("设置:"+n);
32 this.n = n;
33 flag=true;//容器中已经有数据
34 notifyAll();
35 }
36
37
38 }
View Code
Producer:
1 package com.swpu.queue;
2
3 public class Producer implements Runnable{
4 Queue queue;
5 Producer(Queue queue){
6 this.queue=queue;
7 }
8 @Override
9 public void run() {
10 int i=0;
11 while(true){
12 queue.set(i++);
13 try {
14 Thread.sleep(1000);
15 } catch (InterruptedException e) {
16 e.printStackTrace();
17 }
18 }
19 }
20 }
View Code
Consumer:
1 package com.swpu.queue;
2
3 public class Consumer implements Runnable {
4 Queue queue;
5
6 Consumer(Queue queue) {
7 this.queue = queue;
8 }
9
10 @Override
11 public void run() {
12
13 while (true) {
14 queue.get();
15 try {
16 Thread.sleep(1000);
17 } catch (InterruptedException e) {
18 e.printStackTrace();
19 }
20 }
21 }
22
23 }
View Code
Test:
1 package com.swpu.queue;
2
3 public class Test {
4 public static void main(String[] args){
5 Queue queue=new Queue();
6 new Thread(new Producer(queue)).start();
7 new Thread(new Consumer(queue)).start();
8 }
9
10 }
View Code
6.Java各种线程锁:
https://www.jianshu.com/p/fa084227c96b
二.进程
1.什么是进程:
进程是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命周期。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消。反映了一个程序在一定的数据 集上运行的全部动态过程。通过进程控制块(PCB)唯一的标识某个进程。同时进程占据着相应的资源(例如包括cpu的使用 ,轮转时间以及一些其它设备的权限)。是系统进行资源分配和调度的一个独立单位。
2.程序:
一段静态的代码,一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体,是应用软件执行的蓝本。
3.进程和程序的区别:
进程和程序的区别
| 状态 | 是否具有资源 | 是否有唯一标识 | 是否具有并发性 |
进程 | 动态 | √ | √ | √ |
程序 | 静态 | × | √ | × |
4.进程的状态及转换:
(1)就绪(Ready)状态
当进程已分配到除CPU以外的所有必要资源后,只要在获得CPU,便可立即执行,进程这时的状态就称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将他们排成一个队列,称为就绪队列。
(2)执行状态
进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;再多处理机系统中,则有多个进程处于执行状态。
(3)阻塞状态
正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即程序的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。
5.多进程相关实现: