---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
进程与线程
进程:一个进程就是一个执行中的程序。每一个进程都有自己独立的一块内存空间,一组系统资源,在进程的的概念中,每一个进程的内部数据和状态都是完全独立的。
每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
进程是程序的一次执行过程,是系统运行程序的基本单位。
线程:线程是进程中的一个独立的控制单元,线程在控制着进程的执行。一个进程可以拥有多个进程,但一个进程中至少要有一个线程。
线程和进程的主要差别体现在一下俩个方面:
1、 统一作为基本执行单元,线程是划分的比进程更小的执行单位。
2、 每个进程中都有一段专用的内存区域,数据存放空间是独立的,与此相反,线程月共享内存单元(包括代码和数据),通过共享的内存单元来实现数据交换,实时通讯和必要的同步操作。
创建线程
创建线程的方法有两种:一种是继承Thread类创建线程类;另一种是实现Runnable接口创建线程类。
线程状态图
创建线程的第一种方式:继承Thread类。
步骤:
1、定义类继承Thread类。
2、复写Thread类中的run方法。目的:将自定义的代码存储在run方法中,让线程运。
3、创建Thread子类的实例(及创建线程对象)。
4、调用线程的start方法。该方法有两个作用:启动线程,调用run方法。
代码示例:
创建线程的第二种方式:实现Runnable接口。
步骤:
1,定义类实现Runnable接口
2,覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。
3,创建Runnable实现类的实例, 通过Thread类建立线程对象。
4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。//Thread类中存在此构造方法:public Thread(Runnable target).
//为什么要将Runnable接口的子类对象传递给Thread的构造函数?
( 因为,自定义的run方法所属的对象是Runnable接口的子类对象。
所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。)
5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
实现方式和继承方式的区别:
1、Runnable适合于多个相同程序代码线程去处理统一资源的情况,把虚拟的cpu(线程)同程序的代码,数据有效分离,较好体现面向对象的编程的思想。
2、Runnable可以避免由于java的单继承机制带来的局限。可以再继承其他类的同时,还能实现多线程的功能。
3、Runnable能增加程序的健壮性。代码能够被多个线程共享。
无论是继承Thread类的线程,还是实现接口runable的线程都是通过Thread类start()方法调用完成的。
这个类就像是工人,而线程就是工作。
小例子来说明一下:
class A extends Thread
{
}
class B implements runnable
{
}
A 是继承Thread 所以直接调用 start()就行
A a1 = new A() ; // 实例化对象
A a2= new A() ; // 实例化对象
a1.start() ; // 调用线程主体
a2.start() ; // 调用线程主体
B 实现了接口 runnable
B b = new B() ; // 实例化对象
new Thread(b).start() ; // 调用线程主体
new Thread(b).start() ; // 调用线程主体
实现方式是不很不同 A 就像一个工人一个任务;B 则是多个工人一个任务。
Runnable 代码示例:
多线程的安全问题:
视频中毕老师为了让程序出现安全问题,因此调用了Thread类中的静态方法sleep()方法。
sleep()方法介绍 Thread.sleep(longmillis)
sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非
(1)醒来的线程具有更高的优先级。
(2)正在运行的线程因为其它原因而阻塞。
调用方法:
try{thread.sleep(10);}catch{Exception e}
多线程出现安全问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。
解决的办法:
对多条操作共享数据的语句,只能让一个线程都执行完,在执行的过程中,其他的线程都不可以参与执行。
Java对多线程的安全问题提供了专业的解决方法,就是同步。
同步代码块:
Synchronized(对象)
{
需要被同步的代码
}
同步的前提:
1、 必须要有俩个或者俩个以上的线程。
2、 必须是多个线程使用同一个锁。
3、 必须保证同步中只能有一个线程在运行。
同步函数
修饰符synchronized放在返回类型的前面,定义在函数上:public synchronsized void show()对象是this。
如果出现安全问题,如何找问题:
1、明确哪些代码是多线程运行代码
2、明确共享数据
3、明确多线程运行代码中哪些语句是操作共享数据的。
静态的同步函数,如果同步函数被静态修饰后,使用的锁就不再是this了,因为在静态方法中不可以定义this。所以静态方法使用的锁是该方法所在类的字节码文件对象,(对象.class )
---------------------- ASP.Net+Android+IOS开发、 .Net培训、期待与您交流! ----------------------