java 线程(一)

创建Java线程

在Java程序中创建线程有几种方法。每个Java程序至少包含一个线程:主线程。

可以有两种方式创建新的线程:
第一种:
1.定义线程类实现Runnable接口
2.Thread myThread = new Thread(target);   //target为Runnable接口类型
3.Runnable中只有一个方法:public void run();用以定义线程运行体
4.使用Runnable接口可以为多个线程提供共享的数据
5.在实现Runnable接口的类的run()方法定义中可以使用Thread的静态方法public static Thread currentThread();获取当前线程的引用

第二种:

1.可以定义一个Thread的子类并重写其run方法如:
class MyThread extends Thread {    
public void run() {...}
}    
2.然后生成该类的对象:
MyThread myThread = new MyThread();

当我们讨论Java程序中的线程时,也许会提到两个相关实体:完成工作的实际线程或代表线程的Thread对象。正在运行的线程通常是由操作系统创建的;Thread对象是由JavaVM创建的,作为控制相关线程的一种方式。

创建线程和启动线程并不相同

在一个线程对新线程的Thread对象调用start()方法之前,这个新线程并没有真正开始执行。Thread对象在其线程真正启动之前就已经存在了,而且其线程退出之后仍然存在。这可以让您控制或获取关于已创建的线程的信息,即使线程还没有启动或已经完成了。

通常在构造器中通过start()启动线程并不是好主意。这样做,会把部分构造的对象暴露给新的线程。如果对象拥有一个线程,那么它应该提供一个启动该线程的start()或init()方法,而不是从构造器中启动它。

结束Java线程

Java线程会以以下三种方式之一结束:

Java线程到达其run()方法的末尾。

Java线程抛出一个未捕获到的Exception或Error。

另一个Java线程调用一个弃用的stop()方法。弃用是指这些方法仍然存在,但是您不应该在新代码中使用它们,并且应该尽量从现有代码中除去它们。

当Java程序中的所有线程都完成时,程序就退出了。

加入Java线程

ThreadAPI包含了等待另一个线程完成的方法:join()方法。当调用Thread.join()时,调用线程将阻塞,直到目标线程完成为止。

Thread.join()通常由使用线程的程序使用,以将大问题划分成许多小问题,每个小问题分配一个线程。本章结尾处的示例创建了十个线程,启动它们,然后使用Thread.join()等待它们全部完成。

Java线程调度

除了何时使用Thread.join()和Object.wait()外,线程调度和执行的计时是不确定的。如果两个线程同时运行,而且都不等待,您必须假设在任何两个指令之间,其它线程都可以运行并修改程序变量。如果线程要访问其它线程可以看见的变量,如从静态字段(全局变量)直接或间接引用的数据,则必须使用同步以确保数据一致性。

休眠

ThreadAPI包含了一个sleep()方法,它将使当前线程进入等待状态,直到过了一段指定时间,或者直到另一个线程对当前线程的Thread对象调用了Thread.interrupt(),从而中断了线程。当过了指定时间后,线程又将变成可运行的,并且回到调度程序的可运行线程队列中。

如果线程是由对Thread.interrupt()的调用而中断的,那么休眠的线程会抛出InterruptedException,这样线程就知道它是由中断唤醒的,就不必查看计时器是否过期。

Thread.yield()方法就象Thread.sleep()一样,但它并不引起休眠,而只是暂停当前线程片刻,这样其它线程就可以运行了。在大多数实现中,当较高优先级的线程调用Thread.yield()时,较低优先级的线程就不会运行。

守护程序线程

我们提到过当Java程序的所有线程都完成时,该程序就退出,但这并不完全正确。隐藏的系统线程,如垃圾收集线程和由JVM创建的其它线程会怎么样?我们没有办法停止这些线程。如果那些线程正在运行,那么Java程序怎么退出呢?

这些系统线程称作守护程序线程。Java程序实际上是在它的所有非守护程序线程完成后退出的。

任何线程都可以变成守护程序线程。可以通过调用Thread.setDaemon()方法来指明某个线程是守护程序线程。您也许想要使用守护程序线程作为在程序中创建的后台线程,如计时器线程或其它延迟的事件线程,只有当其它非守护程序线程正在运行时,这些线程才有用。

实现生产者消费者问题来说明线程问题,举例如下所示:

  1. /**  
  2. * 生产者消费者问题  
  3. */ 
  4. package com.basic.thread; 
  5. public class ProducerConsumer {  
  6.      /**  
  7.       * @param args  
  8.       */ 
  9.      public static void main(String[] args) {          
  10.          ProductBox pb = new ProductBox();  
  11.          Producer p = new Producer(pb);  
  12.          Consumer c = new Consumer(pb);  
  13.           
  14.          Thread pThread = new Thread(p);  
  15.          Thread cThread = new Thread(c);  
  16.          pThread.setPriority(Thread.MAX_PRIORITY);  
  17.           
  18.          pThread.start();  
  19.          cThread.start();  
  20.      }  
  21. }  
  22. /**  
  23. * 产品对象  
  24. * @author johsnton678  
  25. */ 
  26. class Product {  
  27.      int id;  
  28.      public Product(int id) {  
  29.          super();  
  30.          this.id = id;  
  31.      }  
  32.       
  33.      public String toString(){  
  34.          return "Product:" + id;  
  35.      }  
  36. }  
  37. /**  
  38. * 产品盒对象  
  39. * @author johnston678  
  40. */ 
  41. class ProductBox {  
  42.      Product[] productbox = new Product[6];  
  43.      int index = 0;  
  44.      public ProductBox() {  
  45.          super();          
  46.      }  
  47.       
  48.      public synchronized void push(Product p) {  
  49.          while (index == productbox.length) {  
  50.              try {  
  51.                  this.wait();  
  52.              } catch (InterruptedException e) {  
  53.                  // TODO Auto-generated catch block  
  54.                  e.printStackTrace();  
  55.              }  
  56.          }           
  57.          productbox[index] = p;  
  58.          index = (index + 1)%6;  
  59.    this.notify();
  60.      }  
  61.       
  62.      public synchronized Product pop() {  
  63.          while (index == 0) {  
  64.              try {  
  65.                  this.wait();  
  66.              } catch (InterruptedException e) {  
  67.                  // TODO Auto-generated catch block  
  68.                  e.printStackTrace();  
  69.              }  
  70.          }   
  71.          index = (index - 1 + 6)%6;  
  72.          this.notify(); 
  73.          return productbox[index];  
  74.           
  75.      }  
  76. }  
  77. /**  
  78. * 生产者  
  79. * @author johnston678  
  80. */ 
  81. class Producer implements Runnable {  
  82.      ProductBox productbox = null;  
  83.       
  84.      public Producer(ProductBox productbox) {  
  85.          super();  
  86.          this.productbox = productbox;  
  87.      }  
  88.      @Override 
  89.      public void run() {  
  90.          // TODO Auto-generated method stub  
  91.          for (int i=0; i<10; i++) {  
  92.              Product p = new Product(i);  
  93.              productbox.push(p);  
  94.              System.out.println("produce:" + p);  
  95.               
  96.              try {  
  97.                  Thread.sleep((int)(Math.random() * 200));  
  98.              } catch (InterruptedException e) {  
  99.                  e.printStackTrace();  
  100.              }  
  101.          }  
  102.      }  
  103.       
  104. }  
  105. /**  
  106. * 消费者  
  107. * @author johnston678  
  108. */ 
  109. class Consumer implements Runnable {  
  110.      ProductBox productbox = null;  
  111.       
  112.      public Consumer(ProductBox productbox) {  
  113.          super();  
  114.          this.productbox = productbox;  
  115.      }  
  116.      @Override 
  117.      public void run() {  
  118.          // TODO Auto-generated method stub  
  119.          for (int i=0; i<10; i++) {  
  120.              Product p = productbox.pop();  
  121.              System.out.println("consume:" + p);  
  122.               
  123.              try {  
  124.                  Thread.sleep((int)(Math.random() * 1000));  
  125.              } catch (InterruptedException e) {  
  126.                  e.printStackTrace();  
  127.              }  
  128.          }  
  129.      }  
  130.       

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值