博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java高级篇之进程
阅读量:3963 次
发布时间:2019-05-24

本文共 3820 字,大约阅读时间需要 12 分钟。

一、提高计算机处理效能和速度的主要手段

1、计算机界摩尔定律,由intel公司的一位创始人,现代计算机的硬件在18-24个月在同一价格的基础芯片的集成度会提高一倍。但是硬件的发展不是无限有瓶颈,硬件由金属等物资构成,特质的最小组成单元是原子。电路单元再小不能小过原子。到目前为止该定律仍然是主要定律。

2、阿姆达尔定律,由IBM公司的首席架构师,如果一个系统中存在串行执行的部件,它一定会影响到速度的提升,要想提高计算机的执行速度要求核心部件的加速比要尽量提高。
3、基于第二个定律,各种主流操作系统或开发平台(语言),包括计算机硬件在提升速度这一块都做了改变,硬件方面出现了多核CPU,操作系统的内核也都实现了对进程或线程的支持,从语言上来看,大多数语言也提供了对进程和线程的支持。
4、并行和并发,以后主要提并发不能并行,并发就是在同一时间有多个程序同时执行,或者在同一时间有多个程序在操作一份资源。

二、什么进程

1、进程就是计算机中正在执行的程序。因此进程需要占用计算机的资源及cpu的执行时间。

2、所有进程都由操作系统来分配内存及cpu的执行时间,操作系统是进程的执行基础,主要体现在启动和关闭进程,为它分配资源,在多进程之间调度执行。

3、现代的计算机在启动后,同时会有多个进程在并发的执行。

4、进程具有独立性,不同的进程对应不同的应用程序,实现进程之间的通讯比较困难,现在一般都利用消息队列程序来实现通讯。
5、操作系统给进程一旦分配了内存空间,总的可用空间一般不再变化。
6、当多进程同步执行时,操作系统会为它们分配cpu的时间片,虽然时间片不同,但是因为时间片足够短,所以感觉所有的进程都在同时执行。
在这里插入图片描述

三、线程

线程是进程中的一条执行线索(一个执行单元)。

四、多线程

一个java应用程序就是一个进程,也就是jvm一启动就启动了一个进程,最简单的HelloWorld程序只有一个main方法,main方法本身就是一个执行单元,该方法是由jvm中所生成的一个名称为main的主线程来调用执行的。因此,一般认为main方法就归属于主线程或者说main方法是由主线程来调用的方法。

任何一个java应用程序只有启动起来,就存在着多个线程在执行。因此java应用程序就是多线程。那么多线程也是java语言的一个根本特征。
1、线程共享进程的资源,而不能跨进程获取资源
2、多个线程同属一个进程,因此它们可以共享内存,线程之间的通讯很方便
3、多个线程并发执行可以让进程具有同步处理多个问题的能力,多个用户从服务器下载文件,java进程此时会为每个用户创建一个线程,每个线程都独立的与用户进行通讯,用户的感受就象服务器为他一个服务。其实不然,cpu依靠为各个线程分配时间片,依然是分时操作。线程的执行也需要cpu分配时间片。
4、线程的底层实现原理,现代的主流语言在该问题的解决方案有三种,一是内核态,也就是程序创建的线程其实都是操作系统的内核线程(java 1.2 至今) ,这种创建和管理线程的形态的最大好处在于可以极大的利用操作系统的性能及任务调度的超能力。二、用户态,
线程由语言自已来创建并调度执行,此种方式性能不佳。三、前两者结合在一起,需要高性能时用内核态,一般使用用户态。

五、线程的创建

创建线程要使用Thread类,在java应用程序中一个Thread的对象(实例)就是一条线程。Thrad在lang包中,所以线程具有基础地位,所有的java应用程序都建立在线程的基础之一,没有线程就无所谓java的程序。

1、通过继承Thread来实现线程,在继承的基础上重写run方法,run方法就是线程的执行主体,线程的作用和功能通过run来体现

class MyThread1 extends Thread{
@Override public void run() {
for (int i = 0; i <10 ; i++) {
System.out.println(getName()+"线程 "+i); } }}

2、线程的执行

首先要创建Thread类的对象,然后在对象上调用start()方法来启动线程.

//这样执行run方法,该方法不是线程的主体,只不过是一个普通方法.th1.run();//以下才是启动线程的正确姿势th1.start();MyThread1 th1 = new MyThread1();th1.start();System.out.println("main方法的线程名称:"+Thread.currentThread().getName());

输出 :

main方法的线程名称:main ,这说明main方法是由主线程调用的方法,一个应用程序只有一个主线程,其它的用户线程可以存在多个,但它们都是直接或间接由主线程来创建并启动执行。
Thread-0线程 0
用户自已创建的线程的默认命名规则是:Thread-创建序号,线程序号不能重复,线程越多越大。Jvm底层是通过各线程的名称来识别不同的线程并调度执行,是线程身份的标识。
线程名称也可以由用户自定义,主要有两种方式:
1、通过Thread类的构造方法命名
2、调用Thread类的setName()来命名。 setName(“th1-1”);

2、通过实现Runnable接口来创建线程

Runnable 接口也在 lang包中,该接口只有一个抽象方法,就是run()方法,谁实现该接口,都应当要实现该方法,令该方法作为线程的执行主体,Runnable的对象是线程的执行目标。

3、线程创建及执行的原理

class Thread implements Runnable
Tread本身就实现了Runnable接口,该对象本身就是线程的执行目标,所以只要重写run方法就可以作为线程来执行。

private static native void registerNatives();static {
registerNatives();}

本类注册了一个本地方法,方法名registerNatives()作用是注册一堆本地的方法,说明java的线程是内核态的,因为本地方法才能操作底层(操作系统的接口)的功能。

Static{ }是静态代码块,也是类的成员之一,其作用有两点,一在类被加载时去完成一些任务,二可以对静态变量进行初始化。注意:构造方法对实例变量进行初始化,构造方法的执行时机要晚于静态代码块。
private volatile String name;
此name就是线程名称,它是可见的成员变量,前面带有volatile关键字,如果一个成员变量带volatile,就意味着该变量在内存中的值的改变会即时的让所有的线程得到新值.。
private boolean daemon = false;
Daemon愿意是 “守护”,说明一个新线程默认是用户线程而不是守护线程。
守护线程:如果jvm中没有任何用户线程在执行,那么守护线程就自动终止。
把daemon = true,则当前线程就是守护线程。垃圾回收就是守护线程,所有用户线程停止执行垃圾回收就没必要执行了。
用户线程,只要jvm中有一个用户线程在执行,jvm就不会退出。几乎所有的由设计创建的线程都是用户线程。
private Runnable target;
Thread对象也可接收一个线程执行目标对象(实现了Runnable接口的对象)。

public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);}

传入的target最终交给了Thread对象的target来引用 ,说明如果通过实现Runnable的方式创建的对象来通过构造方法传给Thread,此时线程启动时就会把传入的target当作当前要执行的线程主体。以下代码可以证明。

public void run() {
if (target != null) {
target.run(); }}

如果没有传入target,线程执行谁的代码?

所以如果直接继承Thread,run会被重写,此时调用的是重写的方法而不是Thread的原有的run方法。
4、创建线程两种方式的优缺点
1、继承的方式优点是创建线程简单。缺点是因为java只能单继承,所以一个类继承了Thread将不能再继承其它的类,因此不会特征通过继承实现代码复用及扩展的可能性。
2、实现Runnable接口的方式缺点创建线程时步骤较多,优点,一个类可以实现多个接口,并不会因为实现了Runnable接口而不能去实现其它的接口。实现Runnable接口的对象也是一个普通对象,但是可以作为线程的执行目标,因此实现接口可以让一个类具有多种身份,基于Runnble的一个对象可以创建任意多个线程, 这一点符合面向对象的设计要求;另外,实现了Runnable的类还可以同时继承其它的类。
因此,实现接口的优越性大大大于继承的方式,也是最推荐使用的方式。

转载地址:http://tzzki.baihongyu.com/

你可能感兴趣的文章
P6-c++内存模型和名称空间-02存储连续性、作用域和链接性
查看>>
P9-c++对象和类-02构造函数和析构函数总结
查看>>
P10-c++对象和类-03this指针详细介绍,详细的例子演示
查看>>
Mule ESB-Content-Based Routing Tutorial(1)
查看>>
Mule ESB-Content-Based Routing Tutorial(2)
查看>>
Mule ESB-Content-Based Routing Tutorial(3)
查看>>
年末项目经验总结
查看>>
做事情要放下面子,拿起责任
查看>>
敏捷开发实践(1)-故事工作量估算导致的问题
查看>>
记一次解决jenkins持续构建,自动部署的问题
查看>>
敏捷开发实践(2)-要不要文档?
查看>>
写博意味着什么
查看>>
比较Cint() , int() , fix() ,round()的区别
查看>>
举例说明常用字符串处理函数
查看>>
软件生存期模型
查看>>
制定计划(问题的定义,可行性研究)
查看>>
需求分析
查看>>
软件设计
查看>>
程序编码
查看>>
软件测试
查看>>