论坛首页 入门技术论坛

多线程应用实例

浏览 3654 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-06-10   最后修改:2009-06-10

   关于多线程的,相关的资料网上多的是,下面是我在实际工作中有人问到的最多的问题,现在就写写,和大家一起交流交流哦
    要谈线程首先要知道什么是进程,什么线程?关于书面的解释很多,大家可以网上一搜大把的是在此我就不提了。举个例子吧:

应用程序是进程,那么这个程序在运行过程中做的事情就是线程。

工作:    听写单词        //相当于一个程序
事件1:  老师念           //相当于这个程序中要完成的一项工作
事件2:  学生写           //相当于这个程序中要完成的一项工作

实现多线程有两种方法:一是继承Thread类 ,一是实现Runnable接口

继承Thread 类实例:

import java.util.*;
public class TimePrinter extends Thread {
   int pauseTime;
  String name;
   public TimePrinter(int x, String n) {
       pauseTime = x;
        name = n;
     }
    public void run() {                    //重写了run()方法
        while(true) {
             try {
                System.out.println(name + ":" + new 
                    Date(System.currentTimeMillis()));
               Thread.sleep(pauseTime);
            } catch(Exception e) {
                System.out.println(e);
            }
         }
    }
    static public void main(String args[]) {
         TimePrinter tp1 = new TimePrinter(1000, "间隔1秒");
        tp1.start();                                         //进程由start()函数调用  
        TimePrinter tp2 = new TimePrinter(3000, "间隔3秒");
         tp2.start();
    
     }
 }

 

实现runnable 接口实例:

import java.util.*;
public class TimePrinter2 
        implements Runnable {
    int pauseTime;
    String name;
    public TimePrinter2(int x, String n) {
         pauseTime = x;
         name = n;
     }
     public void run() {
         while(true) {
             try {
                 System.out.println(name + ":" + new 
                     Date(System.currentTimeMillis()));
                Thread.sleep(pauseTime);
             } catch(Exception e) {
                System.out.println(e);
            }
         }
    }
     static public void main(String args[]) {
         Thread t1 = new Thread (new TimePrinter(1000, "间隔1秒"));
         t1.start();                  //进程由start()函数调用  
         Thread t2 = new Thread (new TimePrinter(3000, "间隔3秒"));
         t2.start();
    
    }
 }


此接口只有一个函数,run(),此函数必须由实现了此接口的类实现。

注意,当使用 runnable 接口时,您不能直接创建所需类的对象并运行它;必须从 Thread 类的一个实例内部运行它。许多程序员更喜欢 runnable 接口,因为从 Thread 类继承会强加类层次。

synchronized 同步

出现多个线程访问同一个对象时就会用到synchronized

大多数有用的程序中,线程之间通常有信息流。试考虑一个金融应用程序,它有一个 Account 对象,如下例中所示:

public class Account {
     String holderName;
     float amount;
     public Account(String name, float amt) {
         holderName = name;
         amount = amt;
     }
    public void deposit(float amt) {
        amount += amt;
     }
     public void withdraw(float amt) {
         amount -= amt;
     }
     public float checkBalance() {
         return amount;
     }
 }

 
 在此代码样例中潜伏着一个错误。如果此类用于单线程应用程序,不会有任何问题。但是,在多线程应用程序的情况中,不同的线程就有可能同时访问同一个 Account 对象,比如说一个联合帐户的所有者在不同的 ATM 上同时进行访问。在这种情况下,存入和支出就可能以这样的方式发生:一个事务被另一个事务覆盖。这种情况将是灾难性的。但是,Java 编程语言提供了一种简单的机制来防止发生这种覆盖。每个对象在运行时都有一个关联的锁。这个锁可通过为方法添加关键字 synchronized 来获得。这样,修订过的 Account 对象(如下所示)将不会遭受像数据损坏这样的错误:

public class Account {
     String holderName;
    float amount;
     public Account(String name, float amt) {
         holderName = name;
        amount = amt;
     }
     public 
         synchronized void deposit(float amt) {
         amount += amt;
     }
     public 
         synchronized void withdraw(float amt) {
        amount -= amt;
     }
     public float checkBalance() {
         return amount;
     }
 }

  deposit() 和 withdraw() 函数都需要这个锁来进行操作,所以当一个函数运行时,另一个函数就被阻塞。请注意, checkBalance() 未作更改,它严格是一个读函数。因为 checkBalance() 未作同步处理,所以任何其他方法都不会阻塞它,它也不会阻塞任何其他方法,不管那些方法是否进行了同步处理。

待续,有时间再来补充哦

 

   发表时间:2010-01-21  
受益了 3Q
0 请登录后投票
   发表时间:2010-02-26  
Javac_MyLife 写道
受益了 3Q

受益了      
0 请登录后投票
   发表时间:2010-04-24  
谢了,有用
0 请登录后投票
   发表时间:2010-05-06  
受教了!挺不错的
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics