黑马程序员——多线程

来源:互联网 发布:防骗数据库 编辑:程序博客网 时间:2024/06/03 07:58

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

一、线程

       在计算机中,每一个程序的运行,都是通过线程来实现的。我们可以把一个正在执行的程序称为进程,每一个进程的执行都有一个执行顺序。该顺序是一个执行路径,或者叫控制单元。线程就是进程中的一个独立的控制单元,线程在控制着进程的执行。只要进程中有一个线程在执行,进程就不会结束。一个进程中至少有一个线程。

       在多个程序运行时,CPU会随机地在多个进程中快速切换,哪个线程抢到了CPU的执行权,哪个线程就运行。运行Java程序时,虚拟机启动会有一个java.exe的进程,该进程中至少有一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中,称之为主线程。虚拟机启动除了执行主线程外,还有负责垃圾回收机制的线程。这种在在一个进程中有多个线程执行的方式,就是多线程。

       多线程的出现能让程序产生同时运行的效果,提高程序的运行效率。例如:在虚拟机启动后,进程中执行主线程时,一般会根据程序代码,在堆内存中产生很多对象,而对象调用完后,就成了垃圾,如果不及时清理,垃圾过多容易造成内存不足,影响程序的运行。所以如果只有主线程运行,程序的效率可能会很低;而如果有一个负责垃圾回收机制的线程运行时,就会对堆内存中的垃圾进行清理,保证了内存的稳定,就保证了程序的运行效率。 

二、创建线程

       有两种创建线程的方式:继承Thread类和实现Runnable接口。

       (1)继承Thread类 

             Thread类是Java提供的对线程这类事物描述的类,通过继承Thread类,复写其run方法来创建线程。步骤如下:

            1.定义一个类继承Thread

           2.覆盖Thread中的run方法。将自定义的代码放在run方法中,让线程运行时,执行这些代码。

           3.创建这个类的对象。相当于创建一个线程。然后用该对象调用线程的start方法。该方法的作用是:启动线程,调用run方法。注意如果直接用对象调用run方法,相当于没有启动创建的线程,还是只有主线程在执行。

           覆盖run方法的原因:Thread类用于描述线程。该类就定义了一个功能,用于存储线程要执行的代码。该存储功能就是run方法。也就是说,Thread类中的run方法,用于存储线程要运行的代码。

            

class MyThread extends Thread  {      //覆盖父类的run方法,存入运行代码      public void run(){              for(int x=0;x<1000;x++)            System.out.println(Thread.currentThread().getName()+"在运行");      }  }    class ThreadDemo  {      public static void main(String[] args)       {          //创建线程          MyThread mt1=new MyThread();                  MyThread mt2=new MyThread();                  //启动线程          mt1.start();          mt2.start();          for(int x=0;x<1000;x++)             System.out.println("Hello World!");      }  }  
 


  (2)实现Runnable接口

            实现Runnable接口,覆盖run方法。这种创建线程的方式避免了单继承的局限性,在定义创建线程时,一般都使用这种方式。具体步骤如下:

            1.定义一个类实现Runnable的接口。

           2.覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。

            3.通过Thread类创建线程对象,并将Runnable接口的子类对象作为实际参数传递给Thread类的构造方法。这样做是因为自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去指定对象的run方法,就必须明确该run方法所属对象。

           4.调用Thread类中start方法启动线程。start方法会自动调用Runnable接口子类的run方法。

           

class myRunnable implements Runnable  {           public void run()      {        for(int i=0;i<5;i++)        {              System.out.println(Thread.currentThread().getName()+"....running : "+ i);              }          }  }  class  RunnableDemo  {      public static void main(String[] args)       {        myRunnable t = new myRunnable();                  //创建4个线程        Thread t1 = new Thread(t);          Thread t2 = new Thread(t);          Thread t3 = new Thread(t);          Thread t4 = new Thread(t);          //启动线程                t1.start();          t2.start();          t3.start();          t4.start();       }  } 
 三、线程的运行状态

被创建:等待启动,调用start启动。如果线程已经启动,处在运行时,再次调用start方法,没有意义,会提示线程状态异常。

       运行状态:具有执行资格和执行权。

       临时状态(阻塞):有执行资格,但没有执行权。

       冻结状态:遇到sleeptime)方法和wait()方法时,失去执行资格和执行权,sleep方法时间到或者调用notify()方法时,获得执行资格,变为临时状态。

       消亡状态:stop()方法,或者run方法结束。

四、线程安全

        当多条语句在操作多个线程的共享数据时,当一个线程对多条语句只执行了一部分,还没有执行完时,另一个线程可能就会参与进来执行,这样会导致共享数据的错误。线程的安全问题一旦出现对程序的影响很大。所以Java中提供了解决线程安全问题的方法,叫做同步(synchronized),就是对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行,这样就解决了线程的安全问题。同步中分为两种解决方法,一种是同步代码块,另一种是同步函数

       (1)同步代码块

          格式:synchronized(对象){需要被同步的代码}

     (2)同步函数

             格式:就是在函数上加上synchronized即可。因为非静态函数需要被对象调用,所以非静态函数中都有一个所属对象引用,即this。

同步例子:
class Ticket implements Runnable  {      private  int ticket = 100;      public void run()      {          while(true)               show();          }               //通过同步函数,实现同步。            public synchronized void show()       {              if(ticket>0)          System.out.println(Thread.currentThread().getName()+"....sale : "+ ticket--);        }  }  class  TicketDemo2  {      public static void main(String[] args)       {                  Ticket t = new Ticket();                  Thread t1 = new Thread(t);          Thread t2 = new Thread(t);          Thread t3 = new Thread(t);          Thread t4 = new Thread(t);          t1.start();          t2.start();          t3.start();          t4.start();         }  }  



     



0 0
原创粉丝点击