多线程的应用

 

一、进程和线程的概念

   每个程序运行至少需要一个进程,都有一个执行的路径,在这个进程中又至少有一个线程。我们在电脑上同时开启许多个程序一样,

如果是单核cpu处理器的情况,那么同一时刻cpu只会调度一个线程,而我们视觉上感觉都在并发执行,那是因为cpu在完成快速的切换。

在main函数中,进行着一个主线程,也就是一个程序至少有一个线程。

二、线程的生命周期:

 

 

 

 

  1、创建线程对象

  2、调用start方法,进入就绪状态,等待cpu分配时间片

  3、运行状态:分配到时间片进入运行状态,这个时候线程既有运行资格,又有执行权。

  4、阻塞状态:线程进入阻塞

    调用sleep,线程放弃cpu执行权,等待时间到,进入就绪态

    调用yield,线程放弃当前cpu执行权,重新分配时间片

    调用wait,线程放弃cpu执行权,等待唤醒

    调用join,线程必须等待join的线程执行完,才能继续执行

  5、 结束状态,线程正常执行完任务结束

 

三、创建线程的两种方法:

1、通过继承Thread来创建线程:

  (1)、创建一个子类继承extends  Thread类

  (2)、在子类中重写run()方法。

  (3)、创建一个子类的对象,就是创建了一个线程

  (4)、调用start()方法,启动线程。

 

 

 

 

 

 

2、通过实现Runnable接口来创建线程。

  (1)、创建一个子类来实现Runnable接口

  (2)、重写Runnable接口中的Run()方法

  (3)、在主函数中使用子类创建对象

  (4)、Thread 创建线程,然后把子类对象作为参数传进去。

 

 

 

 

 

 

四、调用run方法和start方法的区别

  如果直接调用run()方法,那么和普通的函数调用没有任何区别,就是先去执行调用函数,然后再返回到主函数中来顺序执行,

其实线程并没有被启动。而调用start()方法,进行了两个步骤,一是启动线程,二是调用run()方法,但是调用之后,线程并没有

进入运行状态,而是出于就绪状态,它有运行资格,但是没有执行权,处于等待cpu分配资源的阶段。

 

五、为什么要覆盖Thread或者接口中的run()方法

  因为run()方法能被线程所调用,所以run()方法中通常是我们要运行的代码,所以,我们在定义一个子类时,要把我们要线程来

执行的程序代码放进去,所以要重写run()方法;

 

六、同步代码块和同步函数

  1、同步代码块的应用,我们知道在多个线程同时操作一段代码时,如果执行到某一句代码时,cpu有可能切换到其他的线程,这样保留

的数据就会改变,不能确保安全性,为了提高代码的安全性,我们要给特定的代码上锁以确定在某一个线程能够执行时,其他的线程进不去。

  格式如下:synchronized(对象){  

        执行代码; 

         }

  同步函数:public  synchronized  void   show(){        

         执行代码;

       }

  给函数或者代码块上锁确实能够提高安全性,但是也耗费了资源,因为线程每次执行都要进行判断,而且如果某线程在执行中睡眠或者

异常,哪怕其他的线程抢到cpu 的执行权,也进不去。  

  2、同步函数中用的锁是this   ,静态同步方法使用锁是该方法所在类的字节码文件对象(类名、class)。

       

七、实现方法和继承方法的区别

  实现方法可以避免单继承的局限性,比如Student类它继承了Person这个类,而它里面需要多线程来完成的代码时,那么它是不能够再去

继承Thread类,所以接口Runnable解决了这个问题。

  1、获取线程名称的方法:Thread.currentThread(),获取当前线程的名称

  2、设置线程名称有两种方式:一是:通过构造函数初始化,然后在super()调用父类的方法;

  二是:通过父类Thread中的方法setName()来完成。

下面通过代码来体现上面的一些概念:

案例一:

 1 public class ThreadDemo {
 2     public static void main(String[] args){
 3         Athread a1=new Athread("线程一");
 4         Athread a2=new Athread("线程二");
 5         //a1.setName("线程一");
 6         //a2.setName("线程二");
 7         a1.start();
 8         a2.start();
 9         for(int x=0;x<60;x++)
10         {
11             System.out.println("Hello,World!");
12         }
13     }
14 }
15 
16 //创建一个类继承Thread线程类
17 class Athread extends Thread {
18     Athread(String name)
19     {
20         super(name);
21     }
22     public void run()//重写Thread中run()方法
23     {
24         for(int i=0;i<60;i++)
25         {
26             System.out.println(Thread.currentThread()+"xiancheng"+i);
27         }
28     }
29 }

 

 


案例二:卖票程序

 1 public class TicketDemo {
 2     public static void main(String[] args) {
 3         Ticket t = new Ticket();
 4         Thread t1 = new Thread(t);
 5         Thread t2 = new Thread(t);
 6         Thread t3 = new Thread(t);
 7         Thread t4 = new Thread(t);
 8         //设置线程名称
 9         t1.setName("线程一");
10         t2.setName("线程二");
11         t3.setName("线程三");
12         t4.setName("线程四");
13         //启动线程
14         t1.start();
15         t2.start();
16         t3.start();
17         t4.start();
18     }
19 }
20 
21 class Ticket implements Runnable {
22     int ticket = 100;
23     Object obj = new Object();
24 
25     public void run() {
26         while (true) {
27             synchronized (obj)//同步代码块,进行上锁
28             {
29                 if (ticket > 0) {
30                     try {
31                         Thread.sleep(10);
32                     } catch (Exception e) {
33                     }
34                     System.out.println("正在卖第" + ticket-- + "张票");
35                 }
36             }
37         }
38     }
39 }


案例三:银行存钱系统

 

 1 public class BankDemo {
 2     public static void main(String[] args) {
 3         Bank b = new Bank();
 4         Thread t1 = new Thread(b);
 5         Thread t2 = new Thread(b);
 6         t1.setName("储户A");
 7         t2.setName("储户B");
 8         t1.start();
 9         t2.start();
10     }
11 }
12 
13 //创建一个类,实现Runnable接口
14 class Bank implements Runnable {
15     Deposit d = new Deposit();
16 
17     public void run() {
18         for (int i = 0; i < 3; i++) {
19             d.add();
20         }
21     }
22 }
23 
24 //定义一个存钱的类
25 class Deposit {
26     int sum = 0;
27     Object obj = new Object();
28 
29     public void add() {
30         synchronized (obj) {
31             sum += 100;
32             System.out.println(Thread.currentThread() + "sum=" + sum);
33         }
34     }
35 }

 

 


 

 

posted @ 2014-10-19 16:26  warrior1234  阅读(269)  评论(0编辑  收藏  举报