----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
进程:正在进行中的程序。
线程:就是进程中一个执行单元或执行情景或执行路径
负责进程中程序执行的控制单元 。
一个进程中至少要有一个线程。
当一个进程中线程有多个时,就是多线程。
多线程解决的问题:可以让多部分代码同时执行。
什么是同时执行呢?其实都是cpu在瞬间做着快速切换完成的。
cpu的切换随机的,按照时间片的方式来完成。
java运行就是多线程的。
在执行main函数中内容的同时,垃圾回收器也在回收堆内存的垃圾。
所以执行main方法的线程,和执行垃圾回收器的线程同时在执行。
这就是多线程。
而且每一个线程都有自己要执行的内容,这个内容称之为:线程的任务。
简单说:
启动线程就是为了执行任务,当任务有多个需要同时执行时,就需要多个线程。
System.gc();//启动了垃圾回收器。垃圾回收器在回收每一个对象垃圾时,都会自动的调用该对象的finalize方法。
在java的lang包中,去找描述线程的类. Thread
通过查阅Thread类的描述,发现
创建线程有两种方式:
方式一:继承Thread类,覆盖run方法。
步骤:
1,定义类继承Thread类。
2,覆盖Thread类中的run方法。
3,创建Thread类的子类对象创建线程对象。
4,调用线程对象的start方法开启线程。
主线程要运行的任务都在main函数中。
自定义的线程要运行的任务都在run方法中。
run方法就是专门用于存储线程任务代码的地方。
要运行线程,必须使用start方法。
start方法做了两件事:1,开启了线程让线程可以运行,2,调用了run方法。
调用run方法和调用start方法的区别:
调用run方法,仅仅是一般对象在调用对象中的方法,并没有开启线程,
还得主线程来完成run方法的运行。
调用start方法,是开启了一个线程(一个新的执行路径。)
这个线程去执行了run方法。
Thread类中的getname方法是返回线程名字。
Thread.currentThread():获取当前执行线程的对象
Thread.currentThread().getName()获取当前执行线程的名字。
例如:main中 d1.run();
d2.run();
而d1=new Demo();
class Demo extends Thread{
public void run(){
System.out.println(Thread.currentThread().getName());结果是当前执行线程对象名main
System.out.println(this.getName());结果是当前的线程子类对象Demo的线程名Thread0
}
}
每个线程都有自己所属的栈区。
多线程的运行状态:
被创建:start()
运行状态:这种状态的线程具备着cpu的执行资格、执行权
消亡状态:stop()或run方法结束
冻结状态:这种状态的线程 ,释放了cpu的执行资格、执行权
临时阻塞状态:这种状态的线程具备着cpu的执行资格,不具备cpu的执行权
由运行状态到冻结状态:sleep(time)此方法time时间一到就可被执行或进入临时阻塞状态(就绪状态);第二种方法就是wait()方法,永久除非notify()唤醒。
创建线程方式二:
1,定义一个类实现Runnable接口。
2,覆盖Runnable接口中的run方法。
将线程要运行的代码存储到run方法中。
3,创建该接口的子类对象。
4,通过Thread类进行线程的创建,并将Runnable接口的子类对象作为Thread类的构造函数的实参进行传递。
为什么要传递呢?
让线程对象创建时,就要明确要运行哪个run方法,而这个run方法是需要被对象调用的,
所以将run方法所属的对象传递给Thread类的构造函数。
5,调用Thread类中的start方法开启线程。
Runnable接口的由来其实就是将线程的任务进行对象的封装。
将线程任务封装成对象后,通过Runnable接口可以降低和Thread对象的耦合性。
如果是继承Thread类,覆盖run方法这种情况,
Thread的子类即封装了线程的任务,而且自身还是一个线程对象。而实现Runnable接口的子类对象只是实现了run()方法,自身并不是一个线程对象。
这就是任务和对象耦合性过高。
Runable接口的出现,线程对象在使用该接口,
我们只要实现该接口即可。将实现的子类对象,也就是线程任务传递给线程对象就哦了。
以后创建线程建议使用第二种方式就是实现Runnable接口的方式。
该方式避免单继承的局限性。
线程安全问题:
安全问题产生的原因:
1,多个线程在操作共享数据。
2,操作共享数据的代码有多条。
一个线程在执行多条操作共享数据的过程中,其他线程参数与了运算,这时就会发生安全问题。
想要分析是否安全问题:
依据:线程任务中有没有共享数据,该数据是否被多条语句操作啊。
解决方案:只要保证一个线程在执行多条操作共享数据的语句时,其他线程不能参与运算即可。
当该线程都执行完后,其他线程才可以执行这些语句。
代码表现:java中给我们提供具体的解决语句。
那就是同步代码块。
格式:
synchronized(对象)//对象可以是任意的对象。
{
需要被同步的语句。
}
同步的原理:其实就是将需要同步的代码进行封装,并在该代码上加了一个锁。
同步的好处:解决多线程的安全问题。
同步的弊端:会降低性能。
同步的前提:
必须要保证在同步中有多个线程。因为同步中只有一个线程该同步是没有意义。
必须要保证多个线程在同步中使用的是同一个锁。
必须保证多个线程使用的锁是同一个。
这时才成为多个线程被同步了。
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------