Java核心API -- 13(线程)

1. 线程相关概念浏览器

    进程:一个操做系统中能够同时运行多个任务(程序),每一个运行的任务(程序)被称为一个进程。安全

    线程:一个程序同时可能运行多个任务(顺序执行流),那么每一个任务(顺序执行流)就叫作一个线程。即在进程内部。多线程

    并发:线程是并发运行的。操做系统将时间化分为若干个片断(时间片),尽量的均匀分配给每个任务,被分配时间片后,任务就有机会被cpu所执行。微观上看,每一个任务都是走走停停的。但随着cpu高效的运行,宏观上看全部任务都在运行。这种都运行的现象称之为并发,但不是绝对意义上的“同时发生”。并发

    线程调度:线程调度机制会将全部并发任务作统一的调度工做,划分时间片(能够被cup执行的时间)给每个任务,时间片尽量的均匀,但作不到绝对均匀。一样,被分配时间片后,该任务被cpu执行,但调度的过程当中不能保证全部任务都是平均的获取时间片的次数。只能作到尽量平均。这两个都是程序不可控的。异步

    线程的启动和中止:void start():想并发操做不要直接调用run方法!而是调用线程的start()方法启动线程!void stop():不要使用stop()方法来中止线程的运行,这是不安全的操做,想让线程中止,应该经过run方法的执行完毕来进行天然的结束。ide


2. 线程的建立方式spa

    1)继承自Thread,而后重写run方法:run方法中应该定义咱们须要并发执行的任务逻辑代码。 操作系统


    案例29:线程

        wKioL1XkHw_Au1k0AAEdp_2fbds855.jpg


    2)实现Runnalbe接口。由于有了这样的设计,才有了线程池。设计

        Runnable接口:用于定义线程要执行的任务逻辑。咱们定一个类实现Runnable接口,这时咱们必须重写run方法,在其中定义咱们要执行的逻辑。以后将Runnable交给线程去执行。从而实现了线程与其执行的任务分离开。将任务分别交给不一样的线程并发处理,可使用线程的重载构造方法:Thread(Runnable runnable)。解藕:线程与线程体解藕,即打断依赖关系。


    案例30:

        wKiom1XkHQuRC71GAAHejxuLVvg919.jpg


    3)线程的建立方式三:使用匿名内部类方式建立线程


    案例31:

        wKiom1XkHYDxqY8DAAGtN4CrDx8701.jpg


3. 线程的生命周期

    线程的生命周期有5种状态:建立(new)、就绪(runnable)、运行(running)、阻塞(block)、死亡(dead)。

    wKiom1XkHbLCs75hAADsuPCiLa4457.jpg

 

4. 线程的经常使用方法

    ① static void sleep(times)方法:让当前线程主动进入Block阻塞状态,并在time毫秒后回到Runnalbe状态。 注意事项:使用Thread.sleep()方法阻塞线程时,强制让咱们必须捕获“中断异常”。 


    案例32:

        wKioL1XkH_XxbiUlAAErD5_kCWM971.jpg


    ② void interrupt()方法:打断/唤醒线程。一个线程能够提早唤醒另一个sleep Block的线程。

        注意事项:方法中定义的类叫局部内部类:局部内部类中,若想引用当前方法的其余局部变量,那么该变量必须是final的。


    案例33:

        wKioL1XkIBGhtZ1IAALm42J1orE541.jpg


    ③ static void yield():当前线程让出处理器(离开Running状态)即放弃当前时间片,主动进入Runnable状态等待。

    ④ final void setPriority(int):设置线程优先级;优先级越高的线程,理论上获取cpu的次数就越多。但理想与现实是有差距的……设置线程优先级必定要在线程启动前设置!


    案例34:

        wKioL1XkIC7wNG47AAItBfgU9Js704.jpg


       

5. wait和notify方法

    这两个方法不是在线程Thread中定义的方法,这两个方法定义在Object中。两个方法的做用是用于协调线程工做的。

        (1) 等待机制与锁机制密切关联:wait/notify方法必须与synchronized同时使用,谁调用wait或otify方法,就锁谁!

        (2) wait()方法:当条将不知足时,则等待。当条件知足时,等待该条件的线程将被唤醒。如:浏览器显示一个图片,displayThread要想显示图片,则必须等代下载线程downloadThread将该图片下载完毕。若是图片没有下杂完成,则dialpayThread能够暂停。当downloadThread下载完成后,再通知displayThread能够显示了,此时displayThread继续执行。

        (3) notify()方法:随机通知、唤醒一个在当前对象身上等待的线程。

        (4) notifyAll方法:通知、唤醒全部在当前对象身上等待的线程。


6. 守护线程

    Daemon后台线程也称为守护线程:当前进程中"全部"、"前台"线程死亡后,后台线程将被强制死亡(非天然死亡),不管是否还在运行。

    ①守护线程,必须在启动线程前调用。

    ②main方法也是靠线程运行的,且是一个前台线程。


    案例35:

        wKiom1XkHjCDw3mxAAJrJu0ibwM526.jpg


7. 线程的并发安全

    多线程在访问同一个数据时(写操做),可能会引起不安全操做。

    ① 同步异步:

        同步:同一时刻只能有一个执行,A和B配合工做,步调一致的处理(B获得A的执行结果才能继续)。如一群人刷卡上公交车。

        异步:同一时刻能有多个执行,并发,各自干各自的。如一群人骑自行车。

    ② synchronized能够修饰方法也能够单独做为语句块存在(同步块)。做用是限制多线程并发时同时访问该做用域。

    ③ synchronized修饰方法后,会为方法上锁。方法就不是异步的了,而是同步的。锁的是当前对象。

    ④ synchronized同步块:分析出只有一段代码须要上锁,则使用。效率比直接修饰方法要高。

    ⑤ 线程安全的效率低,如Vector、Hashtable。线程不安全的效率高,如ArrayList、HashMap 。


    案例36:

        wKioL1XkIHSTH7RdAAHnmxfeAyg719.jpg

        wKioL1XkIKewUQQVAAILI56m_NA805.jpg

相关文章
相关标签/搜索