黑马程序员——多线程

------- 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值