线程和进程

线程和进程

进程

  • 进程是操作系统中运行的一个任务(一个应用程序运行在一个进程中)
  • 进程(process)是一块包含了某些资源的内存区域。操作系统利用进程把它的工作划分为一些功能单元。
  • 进程中所包含的一个或多个执行单元称为线程(thread)。进程还拥有一个私有的虚拟地址空间,该空间仅能被它所包含的线程访问。
  • 线程只能归属于一个进程并且它只能访问该进程所拥有的资源。当操作系统创建一个进程后,该进程会自动申请一个名为主线程或首要线程的线程。

线程

  • 一个线程是进程的一个顺序执行流
  • 同类的多个线程共享一块内存空间和一组系统资源,线程本身有一个供程序执行时的堆栈。线程在切换时负荷小,因此,线程也被称为轻负荷进程。一个进程中可以包含多个线程。

进程与线程的区别

  • 一个进程至少有一个线程。
  • 线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大的提高了程序的运行效率。
  • 线程在执行过程中与进程的区别在于每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  • 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看作多个独立的应用来实现进程的调度和管理以及资源分配。

线程使用的场合

  • 线程通常用于在一个程序中需要同时完成多个任务的情况。我们可以将每个任务定义为一个线程,使他们的已一同工作。
  • 也可以用于在单一线程中可以完成,但是使用多线程可以更快的情况,比如下载文件。

多线程

并发原理:

  • 多个线程“同时”运行只是我们感官上的一种表现。事实上线程是并发运行的,os将时间划分为很多时间片段(时间片),尽可能均匀分配给每一个线程,获取时间片段的线程被cpu运行,而其他线程全部等待。所以微观上是走走停停的,宏观上都在运行。这种现象叫并发,但不是绝对意义上的“同时发生”。
  • 多线程将代码执行的方式改变了,将原有的“串行操作”改为了“并行操作”

线程的状态图:

在这里插入图片描述

创建线程

线程有两种创建方式:

  1. 继承Thread从写run方法
    - 线程的启动和调用
    - 启动线程时要调用线程的start方法。
    - 注意:不要直接调用run方法。
    - 当start方法调用完毕后,该线程纳入到线程调度器中,一旦分配到时间片,那么它的run方法会自动被调用
    - 这种创建线程的方式有两个设计不足:
    1. 由于java是单继承的,这导致若继承了线程就无法再继承其它类去复用方法,这在实际开发中很不方便。
    2. 直接从写run方法来定义线程任务会导致线程与任务存在一个必然的耦合关系,不利于线程的重用。

    public static void main(String[] args) {
    	Thread1 t1 = new Thread1();
    	Thread2 t2 = new Thread2();
    
    	t1.start();
    	t2.start();
    	
    }
    class Thread1 extends Thread{
    	public void run() {
    		for(int i=0;i<1000;i++) {
    			System.out.println("hello");
    		}
    	}
    }
    class Thread2 extends Thread{
    	public void run() {
    		for(int i=0;i<1000;i++) {
    			System.out.println("nihao");
    		}
    	}
    }
    
  2. 第二种创建线程的方式:实现Runable接口单独定义线程任务


public class ThreadDemo2 {

	public static void main(String[] args) {
		MyRunnable1 r1 = new MyRunnable1();
		MyRunnable2 r2 = new MyRunnable2();
		
		Thread t1 = new Thread(r1);
		Thread t2 = new Thread(r2);
		t1.start();
		t2.start();
	}

}
class MyRunnable1 implements Runnable {
	public void run() {
		for(int i=0;i<1000;i++) {
			System.out.println("hello");
		}
	}
}

class MyRunnable2 implements Runnable{
	public void run() {
		for(int i=0;i<1000;i++) {
			System.out.println("NIhao");
		}
	}
}
  1. 使用匿名内部类定义
public static void main(String[] args) {
		Thread t3 = new Thread() {
			public void run() {
				for(int i=0;i<1;i++) {
					System.out.println("开门啊!");
				}
			}
		};
		
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				for(int i=0;i<1;i++) {
					
					System.out.println("别躲在里面不出声");
				}
			}
		});
		
		Runnable r2 = new Runnable() {
			public void run() {
				for(int i=0;i<1;i++) {
					System.out.println("我知道你在家!");
				}
			}
		};
		Thread t2 = new Thread(r2);
		
		t1.start();
		//Thread x = Thread.currentThread();
		
		t2.start();
		t3.start();
		//System.out.println(x);
	}

线程操作API

  • 线程提供了一个静态方法:static Thread currentThread()
    该方法可以获取运行这个方法的线程(它写在哪个方法里就是获取哪个方法的线程)
  • sleep阻塞:static void sleep(long ms)
    • 该方法可以让运行这个方法的线程进入阻塞状态指定毫秒,当超时后线程会自动回到RUNNABLE状态等待再次并发运行
    • sleep方法要求处理中断异常。当一个线程调用sleep方法处于阻塞状态的过程中,若此时该线程的中断方法被调用:interrupt(),那么此时该线程的睡眠阻塞会被立即打断,并在sleep这个方法处抛出中断异常。

注意:JDK8之前有一个要求(JDK8不再要求):当一个方法的局部内部类(定义在方法里的内部类)中引用了这个方法的其他局部变量时,这个变量必须声明为final的,这其实时由于JVM内存分配问题导致的。

  • 线程的优先级:priority
    • 线程的优先级有10个等级,分别用整数1-10表示。1为最低,10为最高,5为默认值
    • 理论上优先级越高的线程获取CPU时间片的次数越多。
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
Java中的线程进程是操作系统中两个基本的概念,它们在执行上下文中有着不同的含义: 1. **进程**(Process): 进程是操作系统分配资源的基本单位,每个进程都有自己的独立内存空间和系统资源。Java程序运行时会创建一个对应的JVM(Java Virtual Machine),JVM中可以有多个并发执行的线程进程的切换是由操作系统内核控制的,切换开销相对较高。 2. **线程**(Thread): 线程是在同一个进程中并行执行的轻量级实体,它们共享同一块内存空间,因此相比于进程线程之间的通信更快、切换更频繁。在Java中,每个Java应用至少有一个主线程,用户可以通过继承Thread类或实现Runnable接口来创建新的线程。 **主要区别**: - **资源占用**:进程拥有独立的内存空间,而线程共享进程的内存,所以线程更节省资源。 - **并发性**:同一进程内的线程可以直接相互访问数据,易于实现并发控制;而不同进程间的数据交换需要通过I/O操作。 - **调度粒度**:进程调度由操作系统进行,线程调度则由JVM或操作系统的用户级线程管理器完成,线程切换更快速。 - **同步与通信**:线程之间通常通过锁、条件变量等同步机制协作,而进程间的通信通常使用管道、消息队列等机制。 **相关问题**: 1. Java如何创建和管理线程? 2. 进程线程在性能优化上有什么考虑? 3. 在并发编程中,为什么要避免不必要的线程创建?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值