浅谈线程

     在说线程之前,有必要说下进程,进程是指程序的一次动态执行过程,或者说进程是正在执行中的程序,其占用特定的地址空间。现代的操作系统,如Windows和UNIX系统,都支持多任务处理,即将CPU的计算时间动态地划分给多个进程,这样操作系统可以同时运行多个进程,这些进程是相互隔离的。独立运行的程序。

     相对于进程,线程是进程中一段连续的控制流程或是一段执行路径。它不能独立存在,必须存在于某个进程中。一个进程可以拥有多个线程,这些线程可以共享进程中内存单元,可以访问相同的变量和对象,以实现线程间通信,数据交换和同步操作等功能。

    在java语言中线程的创建有两种方式:1.定义一个Thread类的子类,并在该类中重写run()方法,该run方法是线程执行的起点;2.定义一个实现Runnable接口的类,并在该类中定义Runnable接口的run()方法,还需要引用Thread类的构造方法,才能真正成为线程对象。

线程的状态:     一个线程对象从创建,启动,运行,终止,直到线程对象被java虚拟机所释放,其生命周期会处于以下四种状态“运行”,“暂停”,“同步”,“挂起”。一个线程对象调用了start()方法后,并不意味着该线程立刻被java虚拟机执行,该线程还需要通过java虚拟机 的调度等待分配给它的CPU计算资源。只有当线程得到了CPU计算资源,它才能真正执行run()方法中所包含的语言,这也是启动是引用start方法,而不是直接引run()方法的原因。

终止:

     当线程对象run()方法中所包含的语句执行完毕,则该线程对象作为一独立的执行逻辑即终止,它就不能再运行了。但该线程对象仍然存在,对此可采用isAlive()方法来判断线程是正在执行当中,还是已经终止。

暂停:

     暂停是指让正在执行的线程暂时停止运行,并在暂停一段时间后,再恢复运行。

sleep()方法是让线程“睡眠”即停止运行 所指定的一段时间,在睡眠结束后,线程立即恢复执行。

join()方法的作用是使当前运行的线程停下来等待,直至所引用join()方法的另一个线程终止。

同步:

     当多个线程对同一数据或对象进行读/写操作时,就需要协调它们对数据的访问,使它们得到数据的一致视图,否则它们之间会互相干扰,在程序中产生不可预期的结果。这种协调机制称为线程的同步。

下面这个列子阐明线程间是如何实现同步的:

 1 package com;
 2 
 3 import java.util.Date;
 4 
 5 public class Demo {
 6 
 7     /**
 8      * @param args
 9      */
10     public static void main(String[] args) {
11         // TODO Auto-generated method stub
12         CubbyHole ch = new CubbyHole();
13         Producer p = new Producer(ch);
14         Consumer c = new Consumer(ch);
15         p.start();
16         c.start();
17     }
18 }
19 
20 class CubbyHole {
21     
22     private int content;
23     private boolean available = false;
24 
25     public synchronized int get() {
26 
27         while (available == false) {
28             try {
29                 wait();
30             } catch (InterruptedException e) {
31                 System.out.println(e);
32                 e.printStackTrace();
33             }
34         }
35 
36         available = false;
37         notifyAll();
38         return content;
39     }
40 
41     public synchronized void put(int value) {
42 
43         while (available == true) {
44             try {
45                 wait();
46             } catch (InterruptedException e) {
47                 System.out.println(e);
48                 e.printStackTrace();
49             }
50         }
51         content = value;
52         available = true;
53         notify();
54     }
55 }
56 
57 class Producer extends Thread {
58 
59     private CubbyHole cubbyhole;
60 
61     public Producer(CubbyHole c) {
62         cubbyhole = c;
63     }
64 
65     public void run() {
66         for (int i = 0; i < 10; i++) {
67             cubbyhole.put(i);
68             System.out.println("Producer " + "put:" + i + ":" + new Date());
69             try {
70                 Thread.sleep((int) Math.random() * 1000);
71             } catch (InterruptedException e) {
72                 System.out.println(e);
73                 e.printStackTrace();
74             }
75         }
76     }
77 }
78 
79 class Consumer extends Thread {
80 
81     private CubbyHole cubbyhole;
82 
83     public Consumer(CubbyHole c) {
84         cubbyhole = c;
85     }
86 
87     public void run() {
88         int value = 0;
89         for (int i = 0; i < 10; i++) {
90             value = cubbyhole.get();
91             System.out
92                     .println("Consumer " + " get:" + value + ":" + new Date());
93 
94         }
95     }
96 }

执行结果:

Producer put:0:Fri May 24 22:40:02 CST 2013
Consumer  get:0:Fri May 24 22:40:02 CST 2013
Consumer  get:1:Fri May 24 22:40:02 CST 2013
Producer put:1:Fri May 24 22:40:02 CST 2013
Consumer  get:2:Fri May 24 22:40:02 CST 2013
Producer put:2:Fri May 24 22:40:02 CST 2013
Producer put:3:Fri May 24 22:40:02 CST 2013
Consumer  get:3:Fri May 24 22:40:02 CST 2013
Consumer  get:4:Fri May 24 22:40:02 CST 2013
Producer put:4:Fri May 24 22:40:02 CST 2013
Consumer  get:5:Fri May 24 22:40:02 CST 2013
Producer put:5:Fri May 24 22:40:02 CST 2013
Producer put:6:Fri May 24 22:40:02 CST 2013
Consumer  get:6:Fri May 24 22:40:02 CST 2013
Producer put:7:Fri May 24 22:40:02 CST 2013
Consumer  get:7:Fri May 24 22:40:02 CST 2013
Producer put:8:Fri May 24 22:40:02 CST 2013
Consumer  get:8:Fri May 24 22:40:02 CST 2013
Producer put:9:Fri May 24 22:40:02 CST 2013
Consumer  get:9:Fri May 24 22:40:02 CST 2013

该实例主要描写了两个线程和一个共享对象间的操作。其中Producer线程是往共享对象CubbyHole中填数,而另一个Consumer线程则是从该共享对象中取数。

线程同步是通过如下两个方面来共同作用而实现的:一是通过关键词 synchronized 给关键对象或数据加锁,这里的关键对象即为CubbyHole对象,;另一方面是利用wait()和notify()方法实现线程间相互等待和唤醒。

posted @ 2013-05-24 23:31  宅山仔  阅读(220)  评论(0编辑  收藏  举报