分享

范例解说Java里的线程概念与线程同步技术 - JAVA专栏

 汲取者 2010-05-06

本文以通俗易懂的范例入手,由浅入深的全面介绍了Java里的线程概念与线程同步技术。

Page:  <1|2>

线程 是一段完成某个特定功能的代码,程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。
进程不同的是,由同名类生成的多个线程共享相同的内存空间和系统资源。

线程与进程的区别:
一个线程是一个程序内部的顺序控制流。
1. 进程:每个进程都有独立的代码和数据空间(进程上下文) ,进程切换的开销大。线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
2. 一个进程中可以包含多个线程。

本文将介绍以下线程方面的知识:
1,线程的创建
2,线程的状态
3,线程同步
4,线程组

理解线程的最有效的方法是通过实例来理解。下面我们将通过 售货员售书 为例,由浅入深地介绍线程的创建,通信,锁机制等概念。

售货员售书
我们 假设一下售货员售书的操作流程:
1,我们假设有20本书,交给2个售货员去卖。
2,售货员可以卖掉任何一本尚未卖出去的书。换句话说,同 一本书若被其中一位售出去了,则不能被另外一位再售出了。


清单1:
文件名 说明
Book.java 书籍类
SellBookRunnable.java 售书类,线程的创建方法之一,该类实现了Runnable 接口,并实现了 run 方法。
SellBookThread.java 售书类,线程的创建方法之一,该类声明为 Thread 的子类,并重写 Thread 类的 run 方法。
CallSellBook.java 调用类。该类分别介绍了2种不同线程创建的调用方法。

Book.java
  1. public class Book {  
  2.     private String name;  
  3.     private boolean sold = false;  
  4.   
  5.     public Book(String name) {  
  6.         this.name = name;  
  7.     }  
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.   
  12.     public void setName(String name) {  
  13.         this.name = name;  
  14.     }  
  15.   
  16.     public boolean isSold() {  
  17.         return sold;  
  18.     }  
  19.   
  20.     public void setSold(boolean sold) {  
  21.         this.sold = sold;  
  22.     }  
  23. }  



SellBookRunnable.java

  1. import java.util.List;  
  2.   
  3. public class SellBookRunnable implements Runnable {  
  4.     private String saleMan;  
  5.     private List<Book> bookList;  
  6.   
  7.     public SellBookRunnable(String saleMan, List<Book> bookList) {  
  8.         this.saleMan = saleMan;  
  9.         this.bookList = bookList;  
  10.     }  
  11.   
  12.     public void run() {  
  13.         for (int i = 0; i < bookList.size(); i++) {  
  14.             Book book = bookList.get(i);  
  15.             sellBook(book);  
  16.         }  
  17.     }  
  18.   
  19.     /** 
  20.      * 售货员卖书。我们这样描述售货员的卖书过程。 
  21.      *  
  22.      * @param book Book 
  23.      */  
  24.     private void sellBook(Book book) {  
  25.         //从开始售书-到售书完成,使用 synchronized (book)保证book不被其他售货员售出  
  26.         synchronized (book) {  
  27.             if (book.isSold()) {  
  28.                 return;  
  29.             } else {  
  30.                 try {  
  31.                     //为了让各线程有执行 机会,设置平均售书时间为0.5秒  
  32.                     Thread.sleep(500);  
  33.                 } catch (Exception e) {  
  34.                 }  
  35.                   
  36.                 //设置已售标志  
  37.                 book.setSold(true);  
  38.                 //打印该书已售信息  
  39.                 System.out.println("[" + saleMan + "]" + book.getName() + " sold out:"  
  40.                         + book.isSold() + ". by "  
  41.                         + Thread.currentThread().getName());  
  42.   
  43.             }  
  44.         }  
  45.     }  
  46. }  



SellBookThread.java

  1. import java.util.List;  
  2.   
  3. public class SellBookThread extends Thread {  
  4.     private String saleMan;  
  5.     private List<Book> bookList;  
  6.   
  7.     public SellBookThread(String saleMan, List<Book> bookList) {  
  8.         this.saleMan = saleMan;  
  9.         this.bookList = bookList;  
  10.     }  
  11.   
  12.     public void run() {  
  13.         for (int i = 0; i < bookList.size(); i++) {  
  14.             Book book = bookList.get(i);  
  15.             sellBook(book);  
  16.         }  
  17.     }  
  18.   
  19.     /** 
  20.      * 售货员卖书。我们这样描述售货员的卖书过程。 
  21.      *  
  22.      * @param book Book 
  23.      */  
  24.     private void sellBook(Book book) {  
  25.         //从开始售书-到售书完成,使用 synchronized (book)保证book不被其他售货员售出  
  26.         synchronized (book) {  
  27.             if (book.isSold()) {  
  28.                 return;  
  29.             } else {  
  30.                 try {  
  31.                     //为了让各线程有执行 机会,设置平均售书时间为0.5秒  
  32.                     Thread.sleep(500);  
  33.                 } catch (Exception e) {  
  34.                 }  
  35.                   
  36.                 //设置已售标志  
  37.                 book.setSold(true);  
  38.                 //打印该书已售信息  
  39.                 System.out.println("[" + saleMan + "]" + book.getName() + " sold out:"  
  40.                         + book.isSold() + ". by "  
  41.                         + Thread.currentThread().getName());  
  42.   
  43.             }  
  44.         }  
  45.     }  
  46. }  



CallSellBook.java

  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3.   
  4. //该类调用SellBookXxx类  
  5. public class CallSellBook {  
  6.   
  7.     /** 
  8.      * 用线程模拟这个售书的过程 
  9.      */  
  10.     public static void main(String[] args) {  
  11.         //方法1:  
  12.         callSellBookThread();  
  13.   
  14.         //or  
  15.           
  16.         //方法2:  
  17.         //callSellBookRunnable();  
  18.     }  
  19.       
  20.     //调用SellBookRunnable(Runnable接 口实现类)模拟售书过程  
  21.     public static void callSellBookThread() {  
  22.         List <Book>bookList = getBookListForSale();  
  23.           
  24.         //将预售书籍清单交给售货员SaleMan1  
  25.         Thread t1 = new SellBookThread("SaleMan1", bookList);  
  26.         //将预售书籍清单交给售货员SaleMan2  
  27.         Thread t2 = new SellBookThread("SaleMan2", bookList);  
  28.   
  29.         //售货员SaleMan1开始售书  
  30.         t1.start();  
  31.         //售货员SaleMan2开始售书  
  32.         t2.start();  
  33.     }  
  34.       
  35.       
  36.     //调用SellBookRunnable(Runnable接 口实现类)模拟售书过程  
  37.     public static void callSellBookRunnable() {  
  38.         List <Book>bookList = getBookListForSale();  
  39.           
  40.         //将预售书籍清单交给售货员SaleMan1  
  41.         Thread t1 = new Thread(new SellBookRunnable("SaleMan1", bookList));  
  42.         //将预售书籍清单交给售货员SaleMan2  
  43.         Thread t2 = new Thread(new SellBookRunnable("SaleMan2", bookList));  
  44.   
  45.         //售货员SaleMan1开始售书  
  46.         t1.start();  
  47.         //售货员SaleMan2开始售书  
  48.         t2.start();  
  49.     }  
  50.   
  51.     //准备预售书籍  
  52.     public static List<Book> getBookListForSale() {  
  53.         List <Book>bookList = new ArrayList();  
  54.         for (int i = 0; i < 20; i++) {  
  55.             Book book = new Book("Book" + i);  
  56.             bookList.add(book);  
  57.         }  
  58.           
  59.         return bookList;  
  60.     }  
  61. }  


执行CallSellBook
[SaleMan1]Book0 sold out:true. by Thread-0
[SaleMan2]Book1 sold out:true. by Thread-1
[SaleMan2]Book2 sold out:true. by Thread-1
[SaleMan2]Book3 sold out:true. by Thread-1
[SaleMan2]Book4 sold out:true. by Thread-1
[SaleMan2]Book5 sold out:true. by Thread-1
[SaleMan1]Book6 sold out:true. by Thread-0
[SaleMan1]Book7 sold out:true. by Thread-0
[SaleMan1]Book8 sold out:true. by Thread-0
[SaleMan1]Book9 sold out:true. by Thread-0
[SaleMan1]Book10 sold out:true. by Thread-0
[SaleMan1]Book11 sold out:true. by Thread-0
[SaleMan2]Book12 sold out:true. by Thread-1
[SaleMan2]Book13 sold out:true. by Thread-1
[SaleMan2]Book14 sold out:true. by Thread-1
[SaleMan2]Book15 sold out:true. by Thread-1
[SaleMan2]Book16 sold out:true. by Thread-1
[SaleMan2]Book17 sold out:true. by Thread-1
[SaleMan1]Book18 sold out:true. by Thread-0
[SaleMan1]Book19 sold out:true. by Thread-0

下一页:线程的创建方法,线程状态,线程同步等

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多