Java线程和进程
一.线程
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构造方法:
构造方法摘要 | |
---|---|
Thread() 分配新的 Thread 对象。 |
|
Thread(Runnable target) 分配新的 Thread 对象。 |
|
Thread(Runnable target, String name) 分配新的 Thread 对象。 |
|
Thread(String name) 分配新的 Thread 对象。 |
|
Thread(ThreadGroup group, Runnable target) 分配新的 Thread 对象。 |
|
Thread(ThreadGroup group, Runnable target, String name) 分配新的 Thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,并作为 group 所引用的线程组的一员。 |
|
Thread(ThreadGroup group, Runnable target, String name, long stackSize) 分配新的 Thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,作为 group 所引用的线程组的一员,并具有指定的堆栈大小。 |
|
Thread(ThreadGroup group, String name) 分配新的 Thread 对象。 |
3.2常用方法:
方法摘要 | |
---|---|
long |
getId() 返回该线程的标识符。 |
String |
getName() 返回该线程的名称。 |
int |
getPriority() 返回线程的优先级。 |
void |
interrupt() 中断线程。 |
static boolean |
interrupted() 测试当前线程是否已经中断。 |
boolean |
isAlive() 测试线程是否处于活动状态。 |
boolean |
isDaemon() 测试该线程是否为守护线程。 |
void |
join() 等待该线程终止。 |
void |
join(long millis) 等待该线程终止的时间最长为 millis 毫秒。 |
void |
join(long millis, int nanos) 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。 |
void |
run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。 |
void |
setName(String name) 改变线程名称,使之与参数 name 相同。 |
void |
setPriority(int newPriority) 更改线程的优先级。 |
static void |
sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 |
static void |
sleep(long millis, int nanos) 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 |
void |
start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。 |
3.3相关方法使用:
(1)继承实现Thread类:
- package com.swpu.thread;
- class MyThread extends Thread{
- public MyThread(String name){
- super(name);
- }
- public void run(){
- for(int i=0;i<10;i++){
- System.out.println(getName()+"正在运行"+(i+1));
- }
- }
- }
- public class ThreadTest {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- MyThread mythread1=new MyThread("线程1");
- MyThread mythread2=new MyThread("线程2");
- mythread1.start();
- mythread2.start();
- }
- }
(2)实现Runnable接口:
为什么要实现Runnable接口:Java不支持多继承了不打算重写Thread类的其他方法。
- package com.swpu.thread;
- class PrintRunnable implements Runnable {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- for (int i = 1; i < 10; i++) {
- System.out.println(Thread.currentThread().getName() + "正在运行"+(i++));
- }
- }
- }
- public class ThreadTest {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- //如果都是使用的pr1,那就相当于资源共享
- PrintRunnable pr1 = new PrintRunnable();
- Thread th1 = new Thread(pr1);
- PrintRunnable pr2 = new PrintRunnable();
- Thread th2 = new Thread(pr2);
- th1.start();
- th2.start();
- }
- }
3.4线程的状态:
3.5正在运行状态---->阻塞状态相关方法使用:
(1)sleep():
在指定的毫秒数内让正在执行的线程休眠(暂停执行),参数是休眠的时间(毫秒)。
使用场景:定期刷新某项东西,计时间等
- package com.swpu.thread;
- class PrintRunnable implements Runnable {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- for (int i = 1; i < 10;) {
- System.out.println(Thread.currentThread().getName() + "正在运行" + (i++));
- //需要捕获异常(运行时退出)
- try {
- //休眠时间结束后,线程不会立即变成执行状态,而是变成可执行状态,需要获取CPU使用权才能变成执行状态
- //因此时间需要多花一点
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public class ThreadTest {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- // 如果都是使用的pr1,那就相当于资源共享
- PrintRunnable pr1 = new PrintRunnable();
- Thread th1 = new Thread(pr1);
- PrintRunnable pr2 = new PrintRunnable();
- Thread th2 = new Thread(pr2);
- th1.start();
- th2.start();
- }
- }
(2)join():
等待该方法的线程结束后才能执行。也有个参数为毫秒,等待线程终止的最长时间为多少毫秒(即在该线程执行的最长时间,无论线程是否结束都会执行其他线程)。
- package com.swpu;
- class MyThread extends Thread {
- public void run() {
- for (int i = 0; i < 10; i++) {
- System.out.println(getName() + "执行第" + (i + 1));
- }
- }
- }
- public class ThreadTest {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- MyThread mythread = new MyThread();
- mythread.start();
- try{
- //抢占资源,会等待Thread-0运行完成后,其他线程才能执行
- mythread.join();
- }
- catch(InterruptedException e){
- e.printStackTrace();
- }
- for(int i=0;i<10;i++){
- System.out.println("主线程运行第"+(i+1));
- }
- }
- }
3.6线程优先级:(优先级的设置与操作系统及工作环境都有关)
Java线程类提供10个优先级;
优先级可以用整个整数1-10表示,超过范围会抛出异常;
主线程默认优先级为5。
优先级常量:MAX_PRIORITY:线程的最高优先级10,MIN_PRIORITY:线程的最低优先级1,NORM_PRIORITY:线程的默认优先级5(主线程为5)
优先级方法:getPriority()获得优先级,setPriority()设置优先级、
- package com.swpu;
- class MyThread extends Thread {
- public void run() {
- for(int i=0;i<50;i++){
- System.out.println(getName()+"运行完成"+(i+1));
- }
- }
- }
- public class ThreadTest {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- int mainPriority=Thread.currentThread().getPriority();
- System.out.println("主线程优先级为:"+mainPriority);
- MyThread mythread1 = new MyThread();
- MyThread mythread2 = new MyThread();
- //设置两个线程的优先级
- mythread1.setPriority(Thread.MAX_PRIORITY);
- mythread2.setPriority(Thread.MIN_PRIORITY);
- mythread1.start();
- mythread2.start();
- }
- }
4.线程中的问题及线程同步:
各个线程是通过竞争CPU时间而获得运行时间的;
各CPU什么时候得到CPU时间,占用多久,是不可预测的;
一个正在运行的线程在什么地方被暂停是不确定的。
线程同步:synchronized关键字用在成员方法,静态方法,语句块。【防止执行过程中语句未执行完整跳到另一个线程,使取得的数据有误差】
5.线程间通信:
wait():在其他线程调用此对象的 notify()
方法或 notifyAll()
方法前,导致当前线程等待;
notify(): 唤醒在此对象监视器上等待的单个线程;
notifyAll(): 唤醒在此对象监视器上等待的所有线程。
例:
Queue:
- package com.swpu.queue;
- public class Queue {
- private int n;
- boolean flag=false;
- public synchronized int get() {
- if(!flag){
- try{
- wait();
- }
- catch(InterruptedException e){
- e.printStackTrace();
- }
- }
- System.out.println("获取:"+n);
- flag=false;//消费完毕
- //唤醒所有线程,notify()随机唤醒一个
- notifyAll();
- return n;
- }
- public synchronized void set(int n) {
- if(flag){
- try{
- wait();
- }
- catch(InterruptedException e){
- e.printStackTrace();
- }
- }
- System.out.println("设置:"+n);
- this.n = n;
- flag=true;//容器中已经有数据
- notifyAll();
- }
- }
Producer:
- package com.swpu.queue;
- public class Producer implements Runnable{
- Queue queue;
- Producer(Queue queue){
- this.queue=queue;
- }
- @Override
- public void run() {
- int i=0;
- while(true){
- queue.set(i++);
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
Consumer:
- package com.swpu.queue;
- public class Consumer implements Runnable {
- Queue queue;
- Consumer(Queue queue) {
- this.queue = queue;
- }
- @Override
- public void run() {
- while (true) {
- queue.get();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
Test:
- package com.swpu.queue;
- public class Test {
- public static void main(String[] args){
- Queue queue=new Queue();
- new Thread(new Producer(queue)).start();
- new Thread(new Consumer(queue)).start();
- }
- }
6.Java各种线程锁:
https://www.jianshu.com/p/fa084227c96b
二.进程
1.什么是进程:
进程是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命周期。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消。反映了一个程序在一定的数据 集上运行的全部动态过程。通过进程控制块(PCB)唯一的标识某个进程。同时进程占据着相应的资源(例如包括cpu的使用 ,轮转时间以及一些其它设备的权限)。是系统进行资源分配和调度的一个独立单位。
2.程序:
一段静态的代码,一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体,是应用软件执行的蓝本。
3.进程和程序的区别:
状态 | 是否具有资源 | 是否有唯一标识 | 是否具有并发性 | |
进程 | 动态 | √ | √ | √ |
程序 | 静态 | × | √ | × |
4.进程的状态及转换:
(1)就绪(Ready)状态
当进程已分配到除CPU以外的所有必要资源后,只要在获得CPU,便可立即执行,进程这时的状态就称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将他们排成一个队列,称为就绪队列。
(2)执行状态
进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;再多处理机系统中,则有多个进程处于执行状态。
(3)阻塞状态
正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即程序的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。
5.多进程相关实现:
https://blog.csdn.net/cq340321/article/details/53364512/
三.相关参考
程序,线程,进程详解:https://www.cnblogs.com/xiohao/p/4310644.html
Java线程和进程的更多相关文章
- java线程与进程
Java线程与进程 进程与线程的关系 进程里面至少有一个线程,进程间的切换会有较大的开销 线程必须依附在进程上,同一进程共享代码和数据空间 多线程的优势 多线程可以达到高效并充分利用cpu 线程使用的 ...
- JAVA线程和进程区别
1,JAVA线程和进程区别? (1)简单来讲一个运行的程序就是一个进程,一个进程中可以有多个线程(线程是程序执行的最小单元). (2)线程有四种状态:运行,就绪,挂起,结束 (3)使用多线程的好处 使 ...
- Java线程和进程相关面试题与答案总结
有几天没有写一写博客了,今天就带给大家一些面试题和参考答案吧! 这些都是上海尚学堂Java培训的学员去面试时遇到的问题,今天总结出来的是Java线程相关类的面试题.把参考答案和解析也发布出来,供大家学 ...
- 关于java线程、进程的一些问题
1.多核硬件上,java中同一个进程的多个线程可以运行在不同的CPU上么? 应该是可以的,在eclipse上面跑一个模拟程序,一个死循环的线程可以占用系统(4核,Win7)%的CPU,4个这样的线程刚 ...
- java线程,进程,多线程
(1)线程和进程 通俗一点,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行. (2)java中实现线程的两种方式,第一种是继承Thre ...
- 菜鸡的Java笔记 第三十七 - java 线程与进程
线程与进程 线程与进程的区别 最早的的时候DOS 系统有一个特点:只要电脑有病毒,那么电脑就死机了,是因为传统的DOS 系统属于单进程的操作系统 ...
- java线程与进程的比较
线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元:而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任 ...
- java线程基础梳理
java线程 概述 进程:运行时概念,运行的应用程序,进程间不能共享内存 线程:应用程序内并发执行的代码段,可以共享堆内存和方法区内存,而栈内存是独立的. 并发理解:在单核机器上,从微观角度来看,一段 ...
- Java中的进程和线程
Java中的进程与线程 一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是 ...
随机推荐
- TLS Thread Local Storage
https://blog.csdn.net/yusiguyuan/article/details/22938671 https://blog.csdn.net/simsunny22/article/d ...
- [Python]在python中调用shell脚本,并传入参数-02python操作shell实例
首先创建2个shell脚本文件,测试用. test_shell_no_para.sh 运行时,不需要传递参数 test_shell_2_para.sh 运行时,需要传递2个参数 test_shell ...
- 阿里JAVA诊断工具Arthas的初步使用
Arthas 是Alibaba开源的Java诊断工具,主要解决以下问题: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? 我改的代码为什么没有执行到?难道是我没 comm ...
- Git代码行数统计命令
统计zhangsan在某个时间段内的git新增删除代码行数 git log --author=zhangsan--since=2018-01-01 --until=2019-04-01 --forma ...
- Linux Openssh源码升级
telnet服务 yum install -y telnet-server xinetd systemctl start xinetd systemctl start telnet.socket #监 ...
- notepad++ 插件说明(一)
notepad++插件说明(一) 1.xml插件安装 下载地址:https://sourceforge.net/projects/npp-plugins/files/XML%20Tools/Xml%2 ...
- 关于ckeditor粘贴图片自动上传
在之前在工作中遇到在富文本编辑器中粘贴图片不能展示的问题,于是各种网上扒拉,终于找到解决方案. 其原理为一下步骤: 监听粘贴事件:[用于插入图片] 获取光标位置:[记录图片插入位置] 获取剪切板内容: ...
- Spring Data JPA 查询
1 按照关键字方法名查询 自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是findBy,readABy,queryBy,getBy,countBy后面跟属性名称 findBy,readAB ...
- Android adb.exe 开发模试安装
1.安装 adb . 让它直接能在cmd 窗口运行 下载:platform-tools 这个就行: Download SDK Platform-Tools for Windows 下载完成后直接解压 ...
- iOS上传图片问题
今天一定得写一篇博客,有以下原因: 1>第一次做图片上传的功能,算是一种记录吧; 2>在这个问题上,纠结,迷茫了很久,主要还是被后台坑了; 1.上传图片的方法是用的AFNetWorking ...