线程 Thread 类,和 Runable 接口 比较两者的特点和应用领域.
可以,直接继承线程Thread类。该方法编写简单,可以直接操作线程,适用于单重继承情况,因而不能在继承其他类
实现Runnable接口。当一个线程已继承了另一个类时,就只能用实现Runnable接口的方法来创建线程,且便于保持程序风格的一致性。
我们知道,一个具有生命的线程,具有下面五种状态:
创建状态
使用new运算符创建一个线程后,该线程仅仅是一个空对象,系统没有分配资源,称该线程处于创建状态(new thread)
可运行状态
使用start()方法启动一个线程后,系统为该线程分配了除CPU外的所需资源,使该线程处于可运行状态(Runnable)
运行中状态
Java运行系统通过调度选中一个Runnable的线程,使其占有CPU并转为运行中状态(Running)。此时,系统真正执行线程的run()方法。
阻塞状态
一个正在运行的线程因某种原因不能继续运行时,进入阻塞状态(Blocked)
死亡状态
线程结束后是死亡状态(Dead)
废话不多说,下面直接上代码:
Java代码:
1 package pack.java.thread.atm; 2 /** 3 * 账户类; 4 * @author Administrator 5 * 6 */ 7 public class Account { 8 9 private String name; //用户名; 10 private int value; //账户余额; 11 12 /** 13 * 存入金额; 14 * @param monery 15 */ 16 public void putMonery(int monery){ 17 this.value = this.value + monery; 18 } 19 20 /** 21 * 取出金额; 22 * @param monery 23 * @return 金额; 24 */ 25 public int getMonery(int monery){ 26 27 //判断是否账户余额是否大于 要取出的钱; 28 if(this.value > monery ){ 29 this.value = this.value - monery; 30 }else{ 31 monery = this.value; //账户余额不够时,则取出,所有的账户余额的金额. 32 this.value = 0; 33 } 34 //返回取出的钱; 35 return monery; 36 } 37 38 /** 39 * 查询余额; 40 * @return 返回账户余额; 41 */ 42 public int search(){ 43 return this.value; 44 } 45 46 public String getName() { 47 return name; 48 } 49 public void setName(String name) { 50 this.name = name; 51 } 52 public int getValue() { 53 return value; 54 } 55 public void setValue(int value) { 56 this.value = value; 57 } 58 }
java代码:
1 import java.io.Serializable; 2 /** 3 * 取款线程类; 4 * @author Administrator 5 * 6 */ 7 public class FetchMoney extends Thread implements Serializable{ 8 9 private static final long serialVersionUID = -5059599151558445815L; 10 11 private Account account; //账户对象; 12 private int monery; //余额; 13 14 public FetchMoney(){ 15 super(); 16 } 17 18 public FetchMoney(int monery,Account account){ 19 this.account = account; 20 this.monery = monery; 21 } 22 23 @Override 24 public void run() { 25 // TODO Auto-generated method stub 26 int currMonery = account.search(); //当前余额; 27 synchronized (account) { 28 try { 29 sleep(5); //取款发费的时间; 30 } catch (InterruptedException e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 } 34 //取出余额; 35 int getMonery = account.getMonery(monery); 36 System.out.println("尊敬的"+account.getName()+"用户您好!"+"当前的余额为:"+currMonery +"元."+"取出余额为:"+getMonery+"元."+"账户余额为:"+account.search()+"元"); 37 } 38 } 39 }
java代码:
1 /** 2 * 存款线程类; 3 * @author Administrator 4 * 5 */ 6 public class SaveMoney extends Thread implements Serializable{ 7 8 private static final long serialVersionUID = 3095120546560212724L; 9 10 private Account account; //账户对象; 11 private int money; //金额; 12 13 public SaveMoney(){ 14 super(); 15 } 16 17 public SaveMoney(int money,Account account){ 18 this.account = account; 19 this.money = money; 20 } 21 22 @Override 23 public void run() { 24 // TODO Auto-generated method stub 25 int currMonery = account.search(); //查询账户余额; 26 27 //同步对象,只允许单线程操作; 28 synchronized (account) { 29 try { 30 sleep(5); //查询的时候,发费得时间; 31 } catch (InterruptedException e) { 32 // TODO Auto-generated catch block 33 e.printStackTrace(); 34 } 35 account.putMonery(this.money); //插入金额; 36 //输出存款信息; 37 System.out.println("尊敬的"+account.getName()+"用户您好!"+"当前的余额为:"+currMonery +"元."+"存入余额为:"+this.money+"元."+"账户余额为:"+account.search()+"元"); 38 } 39 } 40 }
java代码:
1 /** 2 * ATM测试类; 3 * @author Administrator 4 * 5 */ 6 public class ThreadATMDemo { 7 8 /** 9 * 主方法; 10 * @param args 11 */ 12 public static void main(String[] args) { 13 // TODO Auto-generated method stub 14 Account account = new Account(); 15 //设置用户名; 16 account.setName("ZhouHaiTao"); 17 //初始化余额; 18 account.setValue(0); 19 20 //存入100; 21 new SaveMoney(100,account).start(); 22 23 //存入200; 24 new SaveMoney(200, account).start(); 25 26 //取出500; 27 new FetchMoney(500, account).start(); 28 } 29 }
程序运行结果如下:
尊敬的ZhouHaiTao用户您好!当前的余额为:0元.存入余额为:100元.账户余额为:100元
尊敬的ZhouHaiTao用户您好!当前的余额为:0元.存入余额为:200元.账户余额为:300元
尊敬的ZhouHaiTao用户您好!当前的余额为:0元.取出余额为:300元.账户余额为:0元