Java多线程

来源:互联网 发布:微信矩阵营销 编辑:程序博客网 时间:2024/06/06 15:02

一、线程的五种状态

使用Java能方便的写出多线程代码,如果在使用前能了解线程运行时的各种状态,对于理解线程编程会有很大助益
下面从一个示意图来了解一下线程状态:

当一个线程被创建后,调用它的start()方法,使其进入可运行状态,也就说调用完start方法后线程并不会立即运行,而是处于就绪状态。一旦进入运行状态,就会有三种结果:
1、线程执行完毕(死亡)
2、线程由于各种原因,比如说睡眠、运行超时、更高优先级的线程进入、IO等待或join等等,这个时候则暂停运行。
3、在线程运行过程中,调用了某一对象的wait方法,直到其它线程调用此对象的notify或notifyAll 方法,使当前线程恢复可运行状态。可   运行状态指的是java的线程调度器已经通知了操作系统,将这个线程安排到就绪队列,等待CPU执行。


二、线程的概念
     通俗的理解:线程不是一行代码,也不是一个方法,它是一个执行序列。所有代码都在这个序列当中一步步执行至到结束。

 

三、在java中创建线程有两种方法
    1、继承Thread 重写run方法
    2、实现Runnable接口 实现其中的run 方法

 

前面三点了解一下先,接下来看迅雷公司的这道笔试题:

有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…

第一种方法如下:

[java] view plaincopy
  1. package org;  
  2. public class ThreadABC {  
  3.     public static void main(String[] args) {  
  4.         Thread_E tc = new Thread_E();  
  5.         Thread_E tb = new Thread_E();  
  6.         Thread_E td = new Thread_E();  
  7.         Thread_A ta = new Thread_A();  
  8.           
  9.         ta.setThread(tb);  
  10.         tb.setThread(tc);  
  11.         tc.setThread(td);  
  12.         td.setThread(ta);  
  13.           
  14.         ta.setName("A");  
  15.         tb.setName("B");  
  16.         tc.setName("C");  
  17.         td.setName("D");  
  18.           
  19.         ta.start();  
  20.         tb.start();  
  21.         tc.start();  
  22.         td.start();  
  23.           
  24.     }  
  25. }  
  26. class Thread_A extends Thread {  
  27.     Thread t;  
  28.     public void setThread(Thread t) {  
  29.         this.t = t;  
  30.     }  
  31.     public void run() {  
  32.         int i = 0;  
  33.         while(i++ < 10) {  
  34.             System.out.print(Thread.currentThread().getName());  
  35.             t.interrupt();  
  36.             try {  
  37.                 this.join();  
  38.             } catch (InterruptedException e) {  
  39.                   
  40.             }         
  41.         }  
  42.     }  
  43. }  
  44. class Thread_E extends Thread {  
  45.     Thread t;  
  46.     public void setThread(Thread t) {  
  47.         this.t = t;  
  48.     }  
  49.     public void run() {  
  50.         int i = 0;  
  51.         while(i++ < 10) {  
  52.             try {  
  53.                 this.join();  
  54.                   
  55.             } catch (InterruptedException e) {  
  56.                   
  57.             }         
  58.             System.out.print(Thread.currentThread().getName());  
  59.             t.interrupt();  
  60.         }  
  61.     }  
  62. }  

第二种方法如下:

[java] view plaincopy
  1. package com;  
  2. public class PrintABC {  
  3.     public static void main(String[] args) {  
  4.         MajusculeABC maj = MajusculeABC.newInstance();  
  5.         Thread t_a = new Thread(new Thread_ABC(maj , 'A'));  
  6.         Thread t_b = new Thread(new Thread_ABC(maj , 'B'));  
  7.         Thread t_c = new Thread(new Thread_ABC(maj , 'C'));  
  8.         t_a.start();  
  9.         t_b.start();  
  10.         t_c.start();  
  11.     }  
  12. }  
  13. class MajusculeABC {  
  14.     private char charactor = 'A';  
  15.       
  16.     /* 限制此类只创建一个对象 */  
  17.     private static MajusculeABC maObj =null;  
  18.     private MajusculeABC() {}  
  19.     public static MajusculeABC newInstance(){  
  20.         if(maObj == null) {  
  21.             maObj = new MajusculeABC();  
  22.         }  
  23.         return maObj;  
  24.     }  
  25.       
  26.     public void setCharactor() {  
  27.         this.charactor += 1;  
  28.         if(this.charactor == 'D') {  
  29.             this.charactor = 'A';  
  30.         }  
  31.     }  
  32.     public char getCharactor() {  
  33.         return this.charactor;  
  34.     }  
  35.       
  36. }  
  37. class Thread_ABC implements Runnable {  
  38.       
  39.     private MajusculeABC maj;  
  40.     private char charactor = ' ';  
  41.       
  42.     public Thread_ABC(MajusculeABC maj, char charactor) {  
  43.         this.maj = maj;  
  44.         this.charactor = charactor;  
  45.     }  
  46.       
  47.     public void run() {  
  48.         int i = 0;  
  49.         while (i<10) {  
  50.             synchronized (maj) {  
  51.                   
  52.                 while(this.charactor != maj.getCharactor()) {  
  53.                     try {  
  54.                         maj.wait();  
  55.                     } catch (InterruptedException e) {}  
  56.                 }  
  57.                   
  58.                 System.out.print(this.charactor);  
  59.                   
  60.                 i++;  
  61.                   
  62.                 maj.setCharactor();  
  63.                 maj.notifyAll();  
  64.                   
  65.             }  
  66.         }  
  67.           
  68.     }  
  69. }  

以上两种方法都未写注释,第一种方法使用线程中的join() 达到目的,第二种方法就是同步对象

 

对于线程的各种状态、线程间的通信、线程组、线程池等等,下回分解

本文转自http://blog.csdn.net/brilliancezhou/article/details/5504727

原创粉丝点击