您的位置:首页 > 编程语言 > Java开发

JAVA 多线程

2016-09-17 19:37 197 查看
将耗时的、功能独立的模块通过开辟线程的方式解决。



理性认知:

Java是少数的集中支持多线程的语言之一,大多数的语言只能运行单独的一个程序块,无法同时运行不同的多个程序块,Java的多线程机制弥补了这个缺憾,它可以让不同的程序块一起运行,这样可以让程序运行更加顺畅,同时也达到了多任务处理的目的。

1、什么是进程?

进程是:运行中的应用程序。Eclipse/QQ

分配资源:内存(地址空间)和CPU

一个进程包含一个或多个线程。

知识分享:每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。

线程总是属于某个进程,进程中的多个线程共享进程的内存。“同时”执行是人的感觉,在线程之间实际上轮换执行。

进程是程序(任务)执行的过程。执行过程--从字面上看,就是一个动态的过程,一个文件,一个安装包都不是进程,只有运行起来以后才是进程,才有了“生命”。

持有资源(共享内存,共享文件)和线程。这里的资源指的是内存,程序一运行就开始消耗内存。

2、什么是线程?

线程指:程序的执行序列。多个线程共享进程中资源。

3、多线程同时运行的理解:

在Linux的内核处理过程中,每一个线程默认会有一个固定的时间片来执行命令(默认为1/100秒),这段时间内线程被分配到CPU,然后独占使用。

如果使用完,同时未到时间片的规定时间,那么就主动放弃CPU的占用,

如果到时间片尚未完成工作,那么CPU的使用权也会被收回,线程将会被中断挂起等待下一个时间片。

4、创建线程

a、通过继承Thread类,重写run方法。

Thread类实现了Runnable接口。

步骤:

1,定义类继承Thread。

2,复写Thread类中的run方法。

目的:将自定义代码存储在run方法。让线程运行。

3,调用线程的start方法,

该方法两个作用:启动线程,调用run方法。

b、通过实现Runnable接口

编写好一个实现了Runnable的类以后,通过

Thread thread=new Thread(MyRunnable,线程名字)。

步骤:

1,定义类实现Runnable接口

2,覆盖Runnable接口中的run方法。

将线程要运行的代码存放在该run方法中。

3,通过Thread类建立线程对象。

4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

实现方式和继承方式有什么区别呢?

实现方式好处:避免了单继承的局限性。

在定义线程时,建立使用实现方式。

两种方式区别:

继承Thread:线程代码存放Thread子类run方法中。

实现Runnable,线程代码存在接口的子类的run方法。

建议使用实现Runnable接口的方式,避免了单继承带来的缺陷,实现代码的分离,Thread就负责管理线程,而Runnable负责创建执行代码块,实现功能分离。

5、Java对于多线程的安全问题提供了专业的解决方式。

就是同步代码块。

synchronized(对象)

{

需要被同步的代码

}

对象如同锁。持有锁的线程可以在同步中执行。

没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

同步的前提:

1,必须要有两个或者两个以上的线程。

2,必须是多个线程使用同一个锁。

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源.

一个线程start多次,报:IllegalThreadStateException

哪种方式更好--Runnable

1、Runnable可以弥补Java单继承特性带来的缺陷。

2、Runnable只关注任务本身,线程本身的各种方法交给Thread。

补充:1、public修饰的类最多有一个(也可以没有)

2、这个.java文件的类名一定要跟public修饰的类名称一致(main方法基本放于此类中)

3、用javac编译该文件,出现多个.class文件。

6、线程的睡眠

sleep():参数指的是毫秒值。

7、线程的礼让

yield():暂停当前正在执行的线程对象,并执行其他线程。

sleep和yield的区别:

sleep指的是让当前线程进入指定时间内的休眠状态,休眠完成后进入就绪状态,如果持有锁,不释放,yield的意思是当前线程让出资源,立马进入就绪状态。

wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在

任何地方使用

synchronized(x){

x.notify()

//或者wait()

}

sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

8、线程的合并

join()方法:使其他线程等待当前线程停止。

InterruptedException异常:出现的地方--sleep/join/wait/

9、线程的生命周期:

1、新建 new

2、就绪 线程进入可执行序列,start方法,阻塞状态的线程不再阻塞,进入就绪状态。

3、运行

4、阻塞 Thread.sleep/Obj.wait()。

5、死亡

10、线程的优先级。

线程的优先级:1-10. 最大10,最小1,默认5

线程的优先级在start()方法之前调用。

setPriority(int) 设置优先级。

线程的优先级的执行顺序是一种概率事件,优先级高的线程获取到CUP资源的可能性大于优先级低的线程。Java线程中的优先级还跟宿主主机有很大的关系,不建议大家将程序构建的正确性依赖线程的优先级。

11、如何终止一个线程。

a、run方法执行完毕。

b、通过stop方法终止,不过不建议使用,产生问题太多。

c、产生异常或错误

d、编写一个标志,通过标志的值来结束进程。

interrupt()方法,不是用来终止正在运行的线程的,它的作用是:给当前线程设置一个线程终端的标志,通过调用interrupted()来判断线程状态,最后结束线程。

当该线程设置了interrupt()时,线程此时如果受到阻塞sleep/wait,抛出InterruptedException异常。

总结:要想中断一个一直运行的线程,请使用标志的方法退出线程。

12、wait(),sleep()有什么区别?

wait():释放cpu执行权,释放锁。

sleep():释放cpu执行权,不释放锁。

13、线程中的常用方法:

1、start()方法。 //开启线程

2、sleep()方法。 睡眠一定时间,此时交出资源,睡眠结束后进入可执行序列。

3、yield()方法: 交出资源,进入可执行序列。

4、interrupt()方法:给线程设置一个终止的标志。

5、setPriority():设置优先级

6、setDaemon(true):设置守护线程

7、join()方法: 其他线程等待当前线程终止。

8、currentThread():获取当前的线程。

9、setName():设置线程名称。

10、stop():终止线程,已经废弃,不建议使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: