您的位置:首页 > 职场人生

黑马程序员——Java学习笔记之③——“多线程”

2014-03-30 15:16 363 查看
----------- android培训java培训、期待与您交流! ------------

1、进程与线程:

进程:是一个正在执行中的程序,每一个进程都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。

线程:就是进程中的一个独立的控制单元,同时线程也控制着进程的执行。

2,、创建线程的两种方法:

方法1:①定义一个类继承Thread类;

②复写Thread类中的run()方法;(将自定义的代码存储在run方法中,让线程运行)

③调用线程的start()方法。(有两个作用:启动线程,调用run()方法)

方法2:①定义一个类实现Runnable接口;

②覆盖Runnable接口中的run()方法;

③通过Thread类建立线程对象;

④将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数;(定义的run()方法所属的对象是Runnable接口的子类对象,所以要让线程去执行指定对象的run()方法,就必须明确该run()方法所属的对象。)

⑤调用Thread类的start()方法开启线程并调用Runnable接口子类的run()方法。

这两种方法的区别:继承Thread:线程代码存放在Thread子类的run()方法中;而实现Runnable:线程代码存放在接口子类的run()方法中。

实现Runnable的方法的好处:避免了单继承的局限性,且在运行时,每个线程的资源都是独立的。所以在定义线程时,建议使用实现方式。

3、当建立多线程时,每次的运行结果都不同。这是因为多个线程都要获取cpu的执行权,cpu执行到谁,谁就运行。而且cpu在做着快速切换的动作,以达到看上去是同时运行

的效果。即:多个线程在互相抢夺cpu执行权。这就是多线程的随机性:谁抢到cpu,谁执行,至于执行多长时间,cpu说了算。

4、简称的几种运行状态:(下面是我自己整理的各种运行状态的转换示意图)



5、每个线程在建立之初都有自己的默认名称:Thread-(编号),该编号默认从0开始。

Thread类中有两个常用方法:

static Thread currentThread(); 获取当前线程对象。

setName(); (或使用构造函数)设置线程名称。

6、当多个线程共享一个对象时,可将这个对象设置为静态对象。但是一般不推荐使用,应为静态的生命周期太长,太占用系统资源,可能会产生不必要的垃圾。

7、多线程的安全问题:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。

解决办法:对多条操作共享数据的语句:只能让一个线程都执行完。在执行过程中,其他线程不能参与进来执行。

8、Java对于多线程安全问题的解决方式:同步代码块

synchronized(对象) // 这个对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程,即使获取了cpu的执行权也进不去,因为没有持有锁。

{

需要被同步的代码;

}

这种解决方式的好处是:解决了多线程的安全问题。但它有个弊端,就是多个线程需要判断锁,这是较为消耗系统资源的。

当然,同步也是有前提的,首先必须要有两个或者两个以上的线程,再者必须是多个线程使用同一个锁。这样才能保证同步中只有一个线程在运行。

9、简单的多线程编程中要思考的问题:

①要明确哪些代码是多线程运行代码;

②要明确共享数据;

③明确多线程运行代码中哪些是操作共享数据的。

10、关于同步代码块和同步函数中是否使用同一把锁的问题:



11、由于单例设计模式中的懒汉式(延时加载)存在线程安全问题,所以其解决方案如下:



12、多线程中的死锁:由于在同步代码中又嵌套了同步代码,而它们使用的锁却不同,示例如下:



13、wait(); notify(); notifyAll(); 都使用在同步中,因为要对持有监视器(锁)的线程操作。而只有同步才具有锁。而且操作线程的方法要定义Object类中,因为这些方法在操作同步中线程时,都必须要标识它们所操作线程持有的锁。只有同一个锁上的被等待线程,才可以被同一个锁上的notify唤醒。也就是说,等待和唤醒必须是同一个锁,而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中。

14、在jdk1.5中,对多线程安全问题提出了升级方案:Lock接口和Condition接口,将同步Synchronized替换成显式的Lock操作。将Object中的wait,notify,notifyAll,替换成了Condition对象。而且一个Lock对象可以绑定若干个Condition对象。其具体应用如下所示:



15、停止线程的方法:如何停止线程:(stop()方法已过时)只有一种:让run方法结束。

开启多线程运行,运行代码通常是循环结构。只要控制住循环,就能让run方法结束运行,即停止线程。

当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除。强制让线程恢复到运行状态中来,这样就可以操作标记,让线程结束。

Thread类中提供了方法 interrupt();

16、Thread中提供了 setDaemon( boolean bool); 方法用来定义守护线程:它必须在线程调用前定义,相当于后台线程。当前台线程运行结束后,只剩后台线程时,后台线程自动结束运行。(例:输入、输出的情况,就可以将输出线程定义为后台线程,这样当没有输入的时候,输出线程也就没有存在的必要了。)

----------- android培训java培训、期待与您交流! ------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: