Java学习日记----多线程

------- android培训java培训、期待与您交流! ----------

 

1 概述 

  1> 正在进行中的程序称为进程,一个进程中可以有多条件执行路径,如迅雷下载.其中的一个路径就是一个线程,每一个进程执行有一个执行顺序,该顺序就是一个执行路径,或者叫一个控制单元,,线程是进程中一个独立的控制单元,线程在控制着进程的执行.一个进程中至少有一个线程.多线程存在的意义:可以对多部分代码同时执行.

2 创建线程 

  2.1 创建线程的第一种方式 --->继承Thread类  

    1>定义类继承Thread类.  

    2>复写Thread类的run()方法.  

    3>调用线程的start()方法.

      start()方法的作用:启动线程,调用run()方法.  

     run()方法的作用:存储线程要运行的代码.

      注意: d为线程对象    d.start(); --->开启线程并执行线程的run()方法.   

              d.run();   --->仅仅是对象调用方法,线程没有开启.

  2.2运行时发现每一次运行的结果都不一样,因为多线程在获取CPU的执行权,CPU执行到谁,谁就执行,明确一点,在某一时刻,只有一个程序运行(多核CPU除外),CPU在做着快速的切换,以达到看上去是同时执行的结果,我们可以形象的把多线程运行形容为在互相抢夺CPU的资源(执行权),就是多线程的一个特性:随机性.谁抢到就执行谁,至于执行多长时间,CPU说了算. 

  2.3 创建线程的第二种方式 --->实现Runnable接口  

    1>定义类实现Runnable接口.  

    2>重写Runnable中的run()方法.  

    3>通过Thread类建立线程对象.  

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

    5>调用Thread类的start()方法开启线程并调用Runnable接口的子类对象的run()方法. 

  2.4 创建线程的两种方式的区别:  

      继承(Thread):线程代码存放在子类的run()方法中.  

      实现(Runnable):线程代码存放在接口子类的run()方法中.    

      实现方式的好处:避免了单继承的局限性,在定义线程时建议使用实现方式.

3 多线程的安全问题 

  3.1 问题的原因  

      当多条语句在操作同一个线程共享数据时,一个线程对多打语句只执行了一部分,还没有执行完,导致共享数据的错误. 

  3.2 解决的办法  

      对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其它线程不可以参与执行.  

      Java对于多线程的安全问题提供了专业的解决方案---->同步代码块:synchronized(对象   ){需要被同步的代码} 

  3.3 同步代码块   synchronized(对象){需要被同步的代码}

      1> 对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取了CPU的执行权,也进不去.  

      2> 同步的前提:    必须有2个或2个以上的线程,必须是多个线程使用同一个锁.  

      3> 同步的好处和弊端   

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

      弊:有消耗资源的动作(判断锁),但在允许范围内. 

  3.4 同步有两种表现形式:同步代码块和同步函数.  

      同步函数中使用的锁是this,静态同步函数中使用的锁是Class对象.

4 线程间的通信--->等待唤醒机制 

  4.1 wait(),notify(),notifyAll()都使用在同步中,因为要对都有监视器(锁)的线程操作,所以要用在同步中,因为只有同步才有锁的概念. 

  4.2 为什么要将这些操作线程的方法定义的Object类中?  

      因为这些在操作同步中的线程时,都必须要标识它们所操作的线程所持有的锁,只有同一个锁上的被等待线程可以被同一个锁上的notify()唤醒,不可以对不同的锁的线程进行唤醒,也就是说等待和唤醒必须是同一个锁,而锁可以是任意一个对象,可以被任意对象调用的方法只能定义在Object类中 

  4.3 为什么要定义notifyAll()?  

    因为需要唤醒对方线程,只用notify()易出现只唤醒本方线程的情况,还有notify()易导致所有线程都等待的情况. 

  4.4 在JDK1.5中提供多线程的升级解决方案将同步替换成显示Lock操作,将Object类中的wait(),notify(),notifyAll()替换成Condition对象,该对象通过Lock对象获取,实现了本方只唤醒对方的操作.

5 停止线程 

  5.1 stop()方法已经过时,只有一个办法可以让线程停下来---->run()结束.开启多线程时,运行代码友通常是循环结构,只要控制住循环,就可以让run()方法结束,也就是线程结束.但是有一种特殊的情况,当线程处于冻结状态时,就不会读取到标识,那么线程就不会结束.这时可以用interrupt()方法将处于冻结状态的线程强制恢复到运行状态,这样线程就可以读取到标识了,也就可以结束了.

6 守护线程(后台线程) 

  6.1特点:开启后共同和前台线程抢夺CPU资源,当所有前台线程结束后,后台线程会自动结束.其它的没有什么区别.

posted @ 2012-12-08 00:37  叶征东  阅读(123)  评论(0编辑  收藏  举报