黑马程序员 Java基础——进程与线程及多线程
来源:互联网 发布:vmware安装windows xp 编辑:程序博客网 时间:2024/05/29 14:49
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
多线程:
一个应用程序有多条执行路径
进程:正在执行的应用程序
线程:进程的执行单元,执行路径
单线程:一个应用程序只有一条执行路径
多线程:一个应用程序有多条执行路径
当一个进程中出现多个线程是就是多线程。每个线程在栈中都有自己的执行空间、方法区、变量。
java VM启动的时候会有一个进程java.exe。该进程中至少有一个线程负责java程序的执行,而且这个线程运行的代码存在于main方法中。该线程称之为主线程。
多进程的意义
多线程的出现能让程序产生同时运行效果。可以提高程序执行效率。
例如:在java.exe进程执行主线程时,如果程序代码特别多,在堆内存中产生了很多对象,而同时对象调用完后,就成了垃圾。如果垃圾过多就有可能是堆内存出现内存不足的现象,只是如果只有一个线程工作的话,程序的执行将会很低效。而如果有另一个线程帮助处理的话,如垃圾回收机制线程来帮助回收垃圾的话,程序的运行将变得更有效率。
Java程序的运行原理及JVM的启动是多线程的吗?
A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程。
B:JVM的启动是多线程的,因为它最低有两个线程启动了,主线程和垃圾回收线程。
多线程的实现方案(自己补齐步骤及代码 掌握)
A:继承Thread类
B:实现Runnable接口
线程的调度和优先级问题
A:线程的调度
a:分时调度
b:抢占式调度 (Java采用的是该调度方式)
B:获取和设置线程优先级
a:默认是5
b:范围是1-10
线程的控制(常见方法)
A:休眠线程
B:加入线程
C:礼让线程
D:后台线程
E:终止线程
线程的生命周期
A:新建
B:就绪
C:运行
D:阻塞
E:死亡
线程的创建方法
创建线程中第一种方式:继承Thread类。
步骤:
1.定义类继承Thread类。
2.复写Thread类中run方法
目的:将自定义代码存储在run方法,让线程运行。
3.调用线程start方法。
该方法有两个作用:启动线程,调用run方法。
为什么覆盖run方法?
Thread类用于描述线程。该类定义了一个功能,用于存储线程要运行的代码。该存储功能就是run方法。
也就是说Thread类中run方法,用于存储线程要运行的代码。
线程都有自己的名称:Thread-编号该编号从0开始,。
static Thread currentThread();获取当前线程对象。
getName()获取线程名称。
设置线程名称: setName()或者构造函数。
代码实例:
class Demo extends Thread
{
public void run()
{
for(int x=0; x<60; x++)
System.out.println("demo run----"+x);
}
}
class ThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo();//创建好一个线程。
d.start();//开启线程并执行该线程的run方法。
//d.run();//仅仅是对象调用方法。而线程创建了,并没有运行。
for(int x=0; x<60; x++)
System.out.println("Hello World!--"+x);
}
}
第二种方式:实现Runable接口
步骤:
1.定义类实现Runable接口
2.覆盖Runable接口中的run方法。
将线程运行的代码存储在run方法中。
3.通过Thread类建立线程对象。
4.将Runable接口的子类对象作为实际参数传递给Thread类的构造函数。Thread(Runable r)
自定义的run方法所属的对象是Runable接口的子类对象。所以要让线程去运行指定对象的run方法。就必须明确该run方法所属的对象。
5.调用Thread类的start方法开启线程(调用Runable接口子类中的run方法。)
售票实例:
class Ticket implements Runnable//extends Thread
{
private int tick = 100;
public void run()
{
while(true)
{
if(tick>0)
{
System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
}
}
}
}
class TicketDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket();
Thread t1 = new Thread(t);//创建了一个线程;
Thread t2 = new Thread(t);//创建了一个线程;
Thread t3 = new Thread(t);//创建了一个线程;
Thread t4 = new Thread(t);//创建了一个线程;
t1.start();
t2.start();
t3.start();
t4.start();
}
}
两种方式的区别:
继承Thread:线程代码存放Thread子类的run方法中。
实现Runable:线程代码存放在接口的子类的run方法。
实现方式避免了单继承的局限性,在定义线程时,建议使用实现方式。
线程状态:
1.被创建:等待启动,调用start启动。
2.运行状态:具有执行资格和执行权。
3.临时状态(阻塞):有执行资格,但是没有执行权。
4.冻结状态:遇到sleep(time)方法和wait()方法时,失去执行资格和执行权,sleep方法时间到或者调用notify()方法时,获得执行资格,变为临时状态。
5.消忙状态:stop()方法,或者run方法结束。
多线程安全问题:一个线程在运行多条语句、操作同一个数据的时候,其他线程参与进来。导致错误数据的产生。
解决办法:只要让共享数据在某一时间只由一个线程执行,在此过程中其他的不能执行。所以会用到同步 Sychronized(对象){需要被同步的代码}。
对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取CPU的执行权,也进不去,因为没有获取锁
同步函数:用synchronized修饰函数即可。
锁是this。若同步函数被static修饰,所属类.class。
同步的前提:
必须有两个或两个以上线程才需要同步
多个线程必须用同一个锁。
同步的好处是解决的线程安全问题,弊端是需要不断的判断锁,消耗资源。
多线程间通信和一些线程操作方法
线程间通信其实就是多个线程在操作同一个资源,但是操作的动作不同
需要使用的方法有:
wait();
notify();
notifyAll();
上面的方法都使用在同步中,因为要对持有监视器(锁)的线程操作,所以要使用在同步中,因为只有同步才具有锁
为什么这些操作线程的方法要定义在Object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程持有的锁,只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒,也就是说,等待和唤醒必须是同一个锁,而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中。
同步中的死锁问题
何时会出现死锁?当同步中嵌套同步时会出现死锁。这时会出现一个线程持有a锁要想执行下去要获取b锁,而另一个线程持有b锁要想执行下去要获取a锁。这就成了两个线程各自持有一个锁,又要获取对方的锁,这时就出现了死锁。程序会定在那执行不下去。
停止线程
只有一种,run方法结束。开启多线程运行,运行代码通常是循环结构。只要控制住循环,就可以让run方法结束,也就是线程结束。
特殊情况:
当线程处于了冻结状态。就不会读取到标记。那么线程就不会结束。当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除。强制让线程恢复到运行状态中来。这样就可以操作标记让线程结束。Thread类提供该方法 interrupt();
- 黑马程序员 Java基础——进程与线程及多线程
- 黑马程序员——JAVA基础------进程和线程
- 黑马程序员——Java基础--进程与线程的区别
- 黑马程序员—单线程与多线程
- 黑马程序员----JAVA基础----函数与数组及多线程2
- 黑马程序员——Java基础---多线程
- 黑马程序员——Java基础---多线程
- 黑马程序员——Java基础---多线程
- 黑马程序员——Java基础---多线程
- 黑马程序员——Java基础---多线程
- 黑马程序员——java基础---多线程
- 黑马程序员——Java基础多线程
- 黑马程序员——Java基础->多线程
- 黑马程序员——Java基础---多线程
- 黑马程序员——java基础---多线程
- 黑马程序员——Java基础---多线程
- 黑马程序员——java基础--多线程
- 黑马程序员——java基础--多线程
- C语言强制类型转换
- iOS版PhoneGap原理分析
- 使用Maven管理Spring (引用包介绍)
- Android Camera 使用小结
- java执行linux命令方式
- 黑马程序员 Java基础——进程与线程及多线程
- Github上的热门iOS开源项目:AFNetworking、MagicalRecord、BlocksKit以及XVim
- ios如何页面来回跳转,保持动画播放并连贯
- UIViewController各个方法的加载顺序
- iphone开发基础:loadView/viewDidLoad/initWithNibName/awakeFromNib/initWithCoder的用法
- codevs 1026 逃跑的拉尔夫 模拟
- 从JVM内存管理的角度谈谈静态方法和静态属性 和 java对象引用与JVM自动内存管理
- Android studio Gradle home can not be found - Android Studio错误
- 函数类型,函数名是函数指针吗,函数的强制类型转换