进程:
正在运行的程序,是系统进行资源分配和调用的独立单位
每一个进程都有自己的内存空间和系统资源
线程:
是进程中的单个顺序控制流,是一条执行路径
一个进程如果只有一条执行路径,那么称为单线程程序
一个进程如果有多条执行路径,那么称为多线程程序
并行和并发:
并行是逻辑上同时发生,指在某一个时间内同时运行多个程序
并发是物理上同时发生,指在某一个时间点同时运行多个程序
java程序的运行原理:
由java命令启动了JVM,JVM启动就相当于启动了一个进程。
接着由该进程创建了一个主线程去调用main方法
jvm虚拟机的启动是多线程的:
因为垃圾回收线程也要先启动,否则容易出现内存溢出
垃圾回收线程加上前面的主线程,最低启动了两个线程,所以jvm的启动其实是多线程的。
2种方式实现多线程程序
方式一:继承Thread类
步骤:
A:自定义类Mythread继承Thread
B: Mythread类里面重写run()方法
C:创建对象
D:启动线程
注意:不是类中所有的代码都需要被线程执行,为了区别哪些代码能够被线程执行,
java提供了Thread类中的run()用来包含那些被线程执行的代码
run()和start()的区别:
run():仅仅是封装该线程执行的代码,直接调用是普通方法
start():首先启动了线程,然后再由jvm去调用该线程的run()方法
获取线程对象的名称:
public final String getName()
设置线程对象的名称:
public final void setName(String name)
也可以通过带参构造给线程起名字(需要重写Thread的构造方法)
获取main方法所在线程对象的名称:
public static Thread currentThread():返回当前正在执行的线程对象
Thread.currentThread().getName()
获取线程对象的优先级
public final int getPriority():返回线程对象的优先级
注意:线程默认优先级是5
线程优先级的范围是1-10
设置线程对象的优先级:
public final void setPriority(int newPriority):更改线程对象的优先级
线程休眠:
public static void sleep(long millis)
线程控制:
等待该线程终止:public final void join()
礼让线程:
public static void yield():暂停当前正在执行的线程对象,并执行其他线程
让多个线程的执行更和谐,但是不能靠他保证一人一次
守护线程:
public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程
当正在运行的线程都是守护线程时。java虚拟机退出,该方法必须在启动线程前调用
中断线程:
public final void stop():让线程停止,但是已经过时,但是还可以使用
public void interrupt():中断线程,把线程的状态终止,并且抛出一个InterruptedException
线程的生命周期:
新建:创建线程对象
就绪:线程有执行资格,没有执行权
运行:有执行资格,有执行权
阻塞:由于一些操作让线程处于了该状态,没有执行资格,没有执行权
而另一些操作却可以把他给激活,激活后处于就绪状态
死亡:线程对象变成垃圾,等待被回收
方式二:实现Runnable接口
步骤:
A:自定义类MyRunnable实现Runnable接口
B:重写run()方法
C:创建MyRunnable类的对象
D:创建Thread类的对象,并把C步骤的对象作为构造参数传递
相比方式一,方式二的优点:
A:可以有效避免java单继承带来的局限性
B:适合多个相同程序的代码去处理同一个资源的情况,
把线程同程序的代码,数据有效分离,较好的体现了面向对象的设计思想
如何解决线程安全问题:
哪些原因会导致出问题:
A:是否是多线程环境
B:是否有共享数据
C:是否有多条语句操作共享数据
同步代码块:
synchronized(对象) {
需要同步的代码块;
}
同步的特点:
前提:多个线程
解决问题时要注意:多个线程使用的是同一个锁对象
好处:同步的出现解决了多线程的安全问题
弊端:当线程相当多时,因为每个都会去判断同步上的锁,这是很耗费资源的,
无形中会降低程序的运行效率。
同步代码块的锁对象:任意对象
同步方法的格式及锁对象:
把同步关键字synchronized加在方法上
同步方法锁是:this
静态方法锁对象:类的字节码文件对象