1.理解程序,进程,线程的概念?
程序:是由多个进程组成的。可以理解为静态的代码。
进程:可以理解为执行中的程序。
线程:是组成进程的单元,一个进程中有多个线程。我们经常把线程看做是进程中的某一个任务。
2.创建多线程的两种方式(重点)
方式一:继承一个Thread类
方式二:实现一个Runnable接口
两种方式相比较,哪个能好点那?
一般建议是实现Runnable接口的这个方法:原因如下:1.解决了单继承的局限性,2.如果有共享数据的话,还是使用实现这个接口更合适点,因为我们实现多线程的话只需创建一个对象即可,假如要用继承的方式,我们就必须的创建多个对象才能够实现多线程。
多线程中常用的方法?
Threa类中的方法:getName(); setName(String name); getCurrentThread(); start(); run(); sleep(); yield() ; 此时的线程将该对象停止,然后和别的对象重新一起抢占CUP的执行权。
join(); 将该对象先停止,加入另一个对象。将其执行完之后该对象在开始执行 。 isAlive();是否存活
getPriority() 获取优先级 setPriority(int i );设置优先级
Object:中的三个线程通信之间的方法:wait() notify(); notifyAll();
3.线程的声明周期
创建-------->就绪---------->运行-------------------->死亡
4.线程的同步机制
如果我们创建的线程存在着共享数据,那么久有可能存在线程安全的问题,当中的一个线程操作共享数据的时候,还未操作完成,另一个线程参与进来,导致共享数据的操作出现问题。
当线程之前存在着共享数据的时候,才会出现线程安全的问题,反之无共享数据,就不用考虑线程的安全问题。
解决的方式:要求一个线程操作共享数据的时候,只有当其完全操作完成的时候,其他线程还有机会来操作共享数据
方式一:同步代码块:synchronized(监视器){
//操作共享数据
}
注:
1.监视器:俗称锁,就是任何一个类的对象都可以充当锁。
2.实现Runnable接口创建多线程的话,可以用this来代替这个锁,如果是用继承的方式来创建多线程的话,要慎用this,因为thread用回创建多个对象
3.共享数据:多个线程需要共同来操作的变量,要明确那部分是操作共享数据的代码。
方式二:同步方法
public synchronized void show(){
//操作共享数据
}
注:
1.对于非静态的方法而言,使用同步的话,默认锁是:this,如果使用继承方式的话,this要慎用。
2.对于静态的方法而言,使用同步的话,默认锁是:当前类对象,所以继承的方式实现多线程的话不可以用同步方法来实现线程的安全。
总结锁:
会释放锁的方法:wait();
不会释放锁的方法: sleep() yield()
死锁:不同的线程分别占用对方的所须的同步资源不放弃,都在等待对方放弃自己所需要的同步资源,就会形成死锁的!我们在使用同步的时候要避免死锁的出现。
5.线程的通信
1.线程通信的三个方法:
wait(); 等待,此时对象释放了锁,等待对象使用notify()来激活它
notify(); notifyAll(); 激活
注:这三个方法必须在同步代码块或者同步方法中使用!
例题:1-100的交替打印.2生产者消费者的模型