`
Trader
  • 浏览: 8353 次
  • 性别: Icon_minigender_1
  • 来自: 西安
最近访客 更多访客>>
社区版块
存档分类
最新评论

Java 线程一 基础

    博客分类:
  • Java
阅读更多
线程可以共享地址空间。
下面为java实现线程的两种方法,以及启动线程、停止线程、同步线程和线程间通信的Java实现方法。不涉及线程基本理论的讨论。
参考页面:
http://www.3lian.com/zl/2004/10-5/222237.html
http://www.itisedu.com/phrase/200603091754305.html
http://www.javafan.net/article/20040426165025144.html

Java线程要点:
http://www.jdon.com/concurrent/thread.htm
http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=126&threadID=19439&tstart=0
线程基础:

线程(thread)是"进程"中某个单一顺序的控制流。
也被称为轻量进程(lightweight processes)。计算机科学术语,指运行中的程序的调度单位。

  线程是进程中的实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。
线程不拥有系统资源,只有运行必须的一些数据结构;它与父进程的其它线程共享该进程所拥有的全部资源。
线程可以创建和撤消线程,从而实现程序的并发执行。一般,线程具有就绪、阻塞和运行三种基本状态。

  在多中央处理器的系统里,不同线程可以同时在不同的中央处理器上运行,甚至当它们属于同一个进程时
也是如此。大多数支持多处理器的操作系统都提供编程接口来让进程可以控制自己的线程与各处理器之间
的关联度(affinity)。

   有时候,线程也称作轻量级进程。就象进程一样,线程在程序中是独立的、并发的执行路径,
每个线程  有它自己的堆栈、自己的程序计数器和自己的局部变量。
但是,与分隔的进程相比,进程中的线程之间的隔离程度要小。
它们共享内存、文件句柄和其它每个进程应有的状态。

    进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。
一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,
而且它们从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,
但您必须小心,确保它们不会妨碍同一进程里的其它线程。

   一个程序或进程能够包含多个线程,这些线程可以根据程序的代码执行相应的指令。
多线程看上去似乎在并行执行它们各自的工作,就像在一台计算机上运行着多个处理机一样。
在多处理机计算机上实现多线程时,它们确实可以并行工作。
和进程不同的是,线程共享地址空间。也就是说,多个线程能够读写相同的变量或数据结构。

×××××××××××××××××××××××
以上总之一句话,线程可以共享地址空间。
下面为java实现线程的两种方法,以及启动线程、停止线程、同步线程和线程间通信的Java实现方法。
不涉及线程基本理论的讨论。
×××××××××××××××××××××

在Java中实现一个线程有两种方法,第一是实现Runnable接口实现它的run()方法,第二种是继承Thread类,覆盖它的run()方法。下面是代码示例:


  public class DoSomething implements Runnable {
public void run(){
// here is where you do something
}
}
public class DoAnotherThing extends Thread {
public void run(){
// here is where you do something
}
}


这两种方法的区别是,如果你的类已经继承了其它的类,那么你只能选择实现Runnable接口了,因为Java只允许单继承的。

Java中的线程有四种状态分别是:运行、就绪、挂起、结束。如果一个线程结束了也就说明他是一个死线程了。当你调用一个线程实例的start()的方法的时候,这个时候线程进入就绪状态,注意并不是运行状态,当虚拟机开始分配给他CPU的运行时间片的时候线程开始进入运行状态,当线程进入等待状态,例如等待某个事件发生的时候,这时候线程处于挂起状态。

启动一个线程你只需要调用start()方法,针对两种实现线程的方法也有两种启动线程的方法,分别如下:


  DoSomething doIt = new DoSomething();
Thread myThread = new Thread( doIt );
myThread.start();
DoAnotherThing doIt = new DoAnotherThing();
doIt.start();



由于安全等因素Thread中的stop()方法已经不推荐使用了,因此如果你想要停止一个线程的时候可以通过设置一个信号量,例如:


  public class MyThread implements Runnable {
private boolean quit = false;
public void run(){
while( !quit ){
// do something
}
}

public void quit(){
quit = true;
}
}


如果每个线程只做它自己的事情,那么就很简单了,但是有的时候几个线程可能要同时访问一个对象并可能对它进行修改,这个时候你必须使用线程的同步在方法或者代码块使用关键字synchronized,例如:


  public class Counter {
private int counter;
public synchronized int increment(){
return ++counter;
}

public synchronized int decrement(){
if( --counter < 0 ){
counter = 0;
}

return counter;
}
}



每个java对象都可以最为一个监视器,当线程访问它的synchronized方法的时候,他只允许在一个时间只有一个线程对他访问,让其他得线程排队等候。这样就可以避免多线程对共享数据造成破坏。记住synchronized是会耗费系统资源降低程序执行效率的,因此一定要在需要同步的时候才使用,尤其在J2ME的开发中要小心。

如果你要是想让线程等待某个事件的发生然后继续执行的话,那么这就涉及到线程的调度了。在java中通过wait (),notify(),notifyAll()来实现,这三个方法是在Object类中定义的,当你想让线程挂起的时候调用obj.wait()方法,在同样的obj上调用notify()则让线程重新开始运行。 最后以SUN提供的Producer/Consumer的例子来结束这篇文章,内容是 Producer产生一个数字而Consumer消费这个数字,这个小程序里面基本覆盖了本文所有的知识点。请详细研究一下代码


  public class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}

public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("Producer #" + this.number
+ " put: " + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}


public class CubbyHole {
private int contents;
private boolean available = false;

public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) { }
}
available = false;
notifyAll();
return contents;
}

public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) { }
}
contents = value;
available = true;
notifyAll();
}
}

public class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;

public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}

public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("Consumer #" + this.number
+ " got: " + value);
}
}
}
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);

p1.start();
c1.start();
}
}

SUN说输出的结果应该是如下形式


  Producer #1 put: 0
Consumer #1 got: 0
Producer #1 put: 1
Consumer #1 got: 1
Producer #1 put: 2
Consumer #1 got: 2
Producer #1 put: 3
Consumer #1 got: 3
Producer #1 put: 4
Consumer #1 got: 4
Producer #1 put: 5
Consumer #1 got: 5
Producer #1 put: 6
Consumer #1 got: 6
Producer #1 put: 7
Consumer #1 got: 7
Producer #1 put: 8
Consumer #1 got: 8
Producer #1 put: 9
Consumer #1 got: 9
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics