---------------------- android培训 、java培训、期待与您交流!----------------------
一、进程与线程
进程:一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
线程:是线程中一个独立的控制单元,线程在控制着进程的执行。
每一个进程中至少包含一个线程。
二、自定义线程
创建线程的第一种方式:继承Thread类。
1,定义类继承Thread。
2,复写Thread的方法,目的是将自定义的代码存放在run方法中。
3,调用线程的start方法,该方法包含两部分:启动线程和执行run方法。
创建线程的第二种方式:实现Runnable接口。
1,定义类实现Runnable接口。
2,覆盖Runnable接口中的run方法。
3,通过Thread类建立对象。
4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
实现方式和继承方式区别:
继承Thread:线程代码存放在Thread子类中的run方法中。
实现Runnable:线程代码存放在接口的子类run方法中。
在定义线程时,建议使用实现的方式,因为实现方式避免了单继承的局限性,提高了程序的扩展性。
三、线程的状态:
线程共有五种状态,他们之间转换符合一定的条件,如上图。
四、线程的一些操作
Thread类中定了线程的方法,其中currentThread()方法可以获取当前线程对象;getName()方法可以获取线程名称等。
每个线程都有着自己默认的名字,这个名字一般形式为:Thread-编号(线程编号从0开始),可以使用setName方法设置。
五、多线程的安全问题
同步代码块:
synchronized(对象)
{
需要被同步的代码;
}
同步的前提:
1,要有两个及以上的线程;
2,保证是多个线程使用同一个锁。
同步的好处:结局了多线程的安全问题。弊端:由于需要判断锁,所以较为耗费资源。
查找需要被同步代码的方法:
1,明确哪些代码是多线程运行代码。
2,明确哪些是共享数据。
3,明确多线程运行代码中哪些语句是用来操作共享数据的。
同步函数:
synchronized作为修饰符修饰void。
同步函数使用的锁是this。
静态同步函数使用的锁是该类对应的字节码文件(类名.class)。
单例设计模式懒汉式的同步问题:
class Single
{
private static Single s=null;
private Single(){}
public static Single getInstance()
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s=new Single();
}
}
return s;
}
}
通过双重判断并加锁的方式可以避免懒汉式在多线程情况下会出现的安全问题,但是相对代码过多,阅读性不好,所以在多线程参与下建议使用饿汉式。
死锁:同步中嵌套了同步,但是由于内外同步代码使用了不同的锁,相互可能产生冲突,导致程序无法继续执行,即死锁。java中没有处理死锁的机制,所以只能靠程序员手动避免死锁的发生。。
六、线程间通信
等待唤醒机制:
方法:notify()、wait()、notifyAll(),他们都使用在同步中,因为要对持有锁的线程做操作。
其中wait方法会抛出InterruptedException异常,notify方法只唤醒线程池中最先进入的线程,而notifyAll方法唤醒全部线程。
在JDK1.5之后提供了多线程的升级解决方案:
将同步synchronized替换成了Lock操作,将Object类中的notify()、wait()、notifyAll()方法替换成了Condition对象,该对象可以使用lock锁进行获取。
七、停止线程
在当前的java中,停止线程的大部分方法已经被取消,现在停止线程只有一种方法,run方法结束。
在开启多线程运行时,运行代码通常是循环结构,只要控制住循环,就可以让run方法结束。
特殊情况:当线程处于冻结状态,就没有办法读到控制循环的标记,那么线程就不会结束。
Thread类提供了interrupt()方法,该方法可以清楚线程的冻结状态,强制让程序回到运行中来,这样就解决了读取标记线程的冻结情况。
八、其他操作
join方法:可以用来临时加入线程执行。
当A线程执行到B线程的join方法时,A会等待B线程都执行完,A才继续执行。
setDaem:守护线程(类似后台线程)。该线程开启后会与前台线程抢夺CPU资源,当前台所有的线程都执行结束后,它也自动结束。
yield方法:短时间暂停当前执行的线程对象。
toString方法:线程中复写了toString方法,返回的是线程名.优先级.线程组(谁开启的线程)。
setPrority(int x)方法:设置优先级,1到10之间,最小为1:MIN_PRIORITY;最大为10:MAX_PRIORITY;默认为5:NORM_PRIORITY;
---------------------- android培训 、java培训、期待与您交流!----------------------
黑马日记第五篇——多线程
最新推荐文章于 2024-08-16 23:08:28 发布