程序、进程、线程的概念

1.程序:是为了完成某个特定的任务,而用某种语言编写的一组指令的集合,即指的是一段静态的代码,静态对象。

2.进程:是程序的一次执行过程,或是一个正在运行的程序。是一个动态的过程:有它自身的产生、存在、和消亡的过程——生命周期。

程序是静态的,进程是动态的。系统在运行时会为每个进程分配不同的内存空间。 

3.线程:进程可进一步细化为线程,是一个程序内部的执行的路径。若一个进程同一时间并行执行多个线程,就是支持多线程的。线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(PC),一个进程中的多个线程共享相同的内存单元/内存地址空间,可以访问相同的变量和对象,这就使得线程间的通信更简便、高效。但多个线程操作共享系统资源可能会带来安全隐患。

4.创建多线程方式一:继承Thread类

①创建一个继承于Thread类的子类

②重写Thread类的run()--->将此线程的操作声明在run()中

③创建Thread类的子类对象

④通过此对象调用父类的start()--->①启动当前线程 ②调用当前线程的run();

start(),不能重复调用。

在继承Thread类创建多线程的方式中,慎用this充当同步监视器。考虑使用当前类充当同步监视器

5.Thread类的有关方法

①void start(); --->启动线程,并执行对象的run()方法

②run();--->将创建的线程要执行的操作声明在此方法中

③String getName(); 返回线程的名称

④void setName(String name)设置该线程的名称

⑤yield();释放当前CPU的执行权

⑥join();在线程A中调用线程B的join方法,此时线程A就进入阻塞状态,直到线程B完全执行完以后,线程A才结束阻塞状态

⑦stop();已过时,当执行此方法时,强制结束当前线程。

⑧sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒,在指定的millitime毫秒,当前线程是阻塞状态。

⑩isAlive():判断当前线程是否存活。

6.线程的优先级

①MAX_PRIORITY:10 、NORM_PRIORITY:5 (默认优先级)、MIN_PRIORITY:1 

getPriority():获取线程的优先级

setPriority():设置线程的优先级

说明:高优先级线程要抢占低优先级线程的CPU执行权。但是只是从概率上讲,高优先级的线程高概率的情况下被执行。并不意味着只有高优先级线程执行完以后,低优先级线程再执行。

7.创建多线程方式二:

①.创建了一个实现runnable接口的类

②.实现类去实现runnable中的方法:run()

③.创建实现类的对象

④.将此对象作为参数传递到Thread类的构造器当中,创建Thread类的对象

⑤.通过Thread类的对象调用start()方法

8.比较创建线程的两种方式:

开发中,优先选择:实现Runnable接口的方式

①实现的方式没有类的单继承性的局限性

②实现的方式更适合来处理多个线程有共享数据的情况

③不管是继承的方式还是实现的方式都是重写了run(), 将线程要执行的逻辑声明在run()中。

9.创建多线程方式三:

①创建一个实现callable接口的类------JDK5.0新增的

②.实现类去实现callable中的方法:call();将此线程需要执行的操作声明在call()方法中

③.创建实现类的对象

④.将此对象作为参数传递到FutureTask类的构造器当中,创建FutureTask类的对象

⑤.将FutureTask类的对象作为参数传递到Thread类的构造器当中,创建Thread类的对象

⑥.通过Thread类的对象调用start()方法

⑦获取callable中call方法的返回值(不是非必要)

通过FutureTask类的对象调用get()方法,并创建变量来接收。

get返回值即为FutureTask构造器中参数callable实现类重写call()的返回值

10.创建多线程方式四:

①提供指定线程数量的线程池

②调用两种方法execute()、submit()分别适用与Runnable接口或者Callable接口

③执行指定的线程的操作,需要提供实现Runnable接口或者Callable接口实现类的对象

④关闭线程池

处理线程安全的方式

①方式一:

synchronized(同步监视器) {//需要被同步的代码}

说明:操作共享数据的代码,即为需要被同步的代码。——>不能包含代码多了,也不能包含代码少了。

共享数据:多个线程共同操作的变量

同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。

要求:多个线程必须共用同一把锁,

在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器

同步的方式,解决了线程的安全问题。

操作同步代码时,只能有一个线程参与,其他线程等待,相当于是一个单线程的过程,效率低。

②方式二:

关于同步方法的总结:

1.同步方法仍然涉及到同步监视器,只是不需要我们显示地声明。

2.非静态的同步方法,同步监视器:this

静态的同步方法,同步监视器:当前类的本身

③方式三:

1.创建Reentrantlock对象

2.把共享数据加入try/finally中

3.在try中调用锁定的方法,lock()

4.在finally中调用解锁方法,unlock()

辨别synchronized与lock的异同之处:

相同点:二者都可以解决线程安全问题

不同点:synchronized机制在执行完相应的同步代码以后,自动释放同步监视器。

lock需要手动的启动同步lock(),同时结束同步也需要手动的实现unlock()

线程通信

涉及到的三个方法:

1.wait():一旦执行此方法,当前线程就会进入阻塞状态,并释放同步监视器。

2.notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就会唤醒优先级高的那个。

3.notifyAll():一旦执行此方法,就会唤醒被wait的所有线程。

说明:1.wait()、notify()、notifyAll()三个方法必须使用在同步代码块或者同步方法中。

           2.wait()、notify()、notifyAll()三个方法的调用者必须是同步代码块或者同步方法中的同步监视器。否则,会出现异常。

           3.wait()、notify()、notifyAll()三个方法是定义在java.lang.object类中。

sleep()和wait()的异同:

1.相同点:一旦执行此方法,都可以使得当前的线程进入阻塞状态。

2.不同点:①两个方法声明的位置不一样:Thread类中声明sleep(),Object类中声明wait()

②调用的要求不同:sleep()可以在任何需要的场景下调用。wait()必须使用在同步代码块或者同步方法中。

③关于是否释放同步监视器:如果两个方法都使用在同步代码块或者同步方法中,sleep()不会释放同步监视器,wait()会释放同步监视器。

  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱编程的小疯子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值