程序,进程,线程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

程序,进程,线程 ,线程和进程的关系
创建线程
线程优先级
线程状态
守护线程
多线程的概念
线程同步
线程通信
新增创建线程方式

总结


前言

程序、进程、线程的了解与学习


一、程序、进程、线程是什么?

       程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一
段静态的代码.
       进程((process)就是正在执行的程序,从Windows角度讲,进程是操作系统进行
资源 分配 的最小单位.
       线程(thread)进程可进一步细化为线程,是一个进程内部的最小执行单元,是操
作系统进行任务调度的最小单元,隶属于进程.

二、进程、线程的关系是什么?

     1. 一个进程可以包含多个线程,一个线程只能属于一个进程,线程不能脱离进程
而独立运行;
     2.每一个进程至少包含一个线程(称为主线程);在主线程中开始执行程序, java 程序的入口main()方法就是在主线程中被执行的。
     3.在主线程中可以创建并启动其它的线程;
     4.一个进程内的所有线程共享该进程的内存资源。

     线程是进程的分身

相同点:每个线程自然在本质上是一样的,即拥有同样的程序文本。

不同点:但由于是分身,自然也应该有不一样的地方,这就是线程执行时的上下文不一致。 事实上,我们说线程是进程里面的一个执行上下文,或者执行序列。显然,一个进程可以同时拥有多个执行序列。类比进程和线程,每个演员是一个线程,舞台是地址空间,这个同一个地址空间里面的所有线程就构成了进程。在线程模式下,一个进程至少有一个线程,但也可以有多个线程。

优点:将进程分解为线程还可以有效利用多处理器和多核计算机。 在没有线程的情况下,增加一个处理器并不能让一个进程的执行速度提高。但如果分解为多个线程,则可以让不同的线程同时运转在不同的处理器上,从而提高了进程的执行速度。

线程管理:有进程后,要管理进程。那么有线程后,也要进行管理。而管理的基础也与进程管理的基础类似:就是要维持线程的各种信息,这些信息包含了线程的各种关键资料。存放这些信息的数据结构称为线程控制表或线程控制块。

线程的实现方式:
既然线程是进程的构成部分,或者是进程的分身,那么由谁来管理线程就有两种选择:一是让进程自己来管理线程;二是让操作系统来管理线程,这种不同的选择就出现了内核态线程和用户态线程。这也是线程实现的两种方式。由进程自己管理就是用户态线程实现,由操作系统管理就是内核态线程实现。

二、创建线程

1.继承Thread类的方式

代码如下定义与调用:

public class MyThread extends Thread {
               public void run() {
               }
}
MyThread thread = new MyThread();
thread.start();

Thread类中常用方法:

void start()     启动线程
final String getName()     返回线程的名称
final void setPriority(int newPriority)     设置线程的优先级
final int getPriority()      返回线程的优先级
final void join()        等待线程终止
static Thread currentThread()        返回对当前正在执行的线程对象的引用
static void sleep(long millis)       让当前正在执行的线程休眠(暂停执行), 休眠时间由milli s(毫秒)指定
yield()       线程让步

2.实现Runnable接口的方式

代码如下(示例):

java.lang.Runnable接口中仅仅只有一个抽象方法:

public void run()

public class MyThread implements Runnable{
            @Override
            public void run() {
                     ……
             }
}
线程执行任务
MyThread r = new MyThread();
创建一个线程作为外壳,将r包起来,
Thread thread = new Thread(r);
thread.start();

实现Runable的好处

1.避免了单继承的局限性
2.多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处
理同一份资源。

三、线程优先级

计算机只有一个CPU,各个线程轮流获得CPU的使用权,才能 执行任务;
优先级较高的线程有更多获得CPU的机会,反之亦然;
优先级用整数表示,取值范围是1~10,一般情况下,线程的默认优先级 都是5,但是也可以通过setPriority和getPriority方法来设置或返回优先级;
调度策略

● 时间片

● 抢占式:高优先级的线程抢占CPU

Thread类有如下3个静态常量来表示优先级

     MAX_PRIORITY:取值为10,表示最高优先级。
     MIN_PRIORITY:取值为1,表示最底优先级。
     NORM_PRIORITY:取值为5,表示默认的优先级。

四、线程状态

线程的状态:
1.新建 :当一个Thread类或其子类的对象被声明并创建时,新生的线程对
象处于新建状态
2.就绪: 处于新建状态的线程被start()后,将进入线程队列等待CPU时
间片,此时它已具备了运行的条件,只是没分配到CPU资源
3.运行: 当就绪的线程被调度并获得CPU资源时,便进入运行状态,run
()方法定义了线程的操作和功能
4.阻塞: 在某种特殊情况下,被人为挂起或执行输入输出操作时,让出
CPU并临时中止自己的执行,进入阻塞状态
5.死亡: 线程完成了它的全部工作或线程被提前强制性地中止或出现异常
导致结束

å¾ç

五、守护线程 

Java线程分为用户线程和守护线程。

守护线程:守护线程是程序运行的时候在后台提供一种通用服务的线程。所有用户线程停止,进程会停掉所有守护线程,退出程序。

方法:Java中把线程设置为守护线程的方法:在 start 线程之前调用线程的 setDaemon(true) 方法。

注意:setDaemon(true) 必须在 start() 之前设置,否则会抛出IllegalThreadStateException异常,该线程仍默认为用户线程,继续执行
守护线程创建的线程也是守护线程
守护线程不应该访问、写入持久化资源,如文件、数据库,因为它会在任何时间被停止,导致资源未释放、数据写入中断等问题

六、多线程的概念

        多线程是指程序中包含多个执行单元,即在一个程序中可以同时运行多 个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行 执行的线程来完成各自的任务。

多线程的实现一般有两种形式:

1.通过继承Thread类实现,重新其中的run()方法,通过start方法进行调用;

2.通过实现Runnable接口,进行任务分配进行实现,在线程池中支持该实现方式。
线程的调用通过start,救赎通过sleep,stop方法因为资源占用的问题已经停止使用。

优点:

1.使用线程可以把占据时间长的程序中的任务放到后台去处理;提高cpu利用率;改善程序结构,将复杂任务分为多个线程,独立运行。;在一些等待的任务实现上,如用户输入,文件读写和网络收发数据等,线程就比较有用。在这种情况下可以释放一些珍贵的资源如内存占用等。

缺点:

线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
多线程需要协调和管理,所以需要CPU时间跟踪线程;
线程之间对共享资源的访问会相互影响

七、线程同步

并发与并行
       并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事。
       并发:在一个时间段内一次执行操作.例如卖票,抢购,秒杀看似同时进行,
实际是一个一个执行.
在Java代码中实现同步:
使用synchronized(同步锁)关键字同步方法或代码块。
synchronized (同步锁){
// 需要被同步的代码;
}
synchronized还可以放在方法声明中,表示整个方法,为同步方法。
例如:
public synchronized void show (String name){
// 需要被同步的代码;
}

八、线程通信

概念:线程通讯指的是多个线程通过相互牵制,相互调度,即线程间的相互作用。
涉及三个方法:
.wait一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
.notify一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,
就唤醒优先级高的那个。
.notifyAll一旦执行此方法,就会唤醒所有被wait的线程。
注意:
.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方
法中。

九、新增创建线程方式

       实现Callable接口与使用Runnable相比,Callable功能更强大些.
       相比run()方法,可以有返回值
       方法可以抛出异常
       支持泛型的返回值
       需要借助FutureTask类,获取返回结果
接收任务
FutureTask<Integer> futureTask = new FutureTask(任务);
创建线程
Thread t = new Thread(futureTask);
t.start();
Integer val = futureTask.get();获得线程call方法的返回值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只求学猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值