Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
很多人搞C++的人可能一看到多线程就比较烦吧,因为C++标准里面没有多线程,Java程序员应该感到庆幸了,因为Java内带的支持多线程。
1.什么是多线程??

多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。

  线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。

  多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的,但是由于CPU的速度非常快,用户感觉不到其中的区别,因此我们也不用关心它,只需要设想各个线程是同时执行即可。

  多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的,需要有线程调度,同步等问题。

 

2.Java中实现多线程的方法

(1).继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可

public class MyThread extends Thread
  {
  int count= 1, number;
  public MyThread(int num)
  {
  number = num;
  System.out.println
  ("创建线程: " +number);
  }
  public void run() {
  while(true) {
  System.out.println
  ("线程 :" +number +"   计数: " count);
  if( count== 6) return;
  }
  }
  public static void main(String args[])
  {
  for(int i = 0; i〈 5; i++ )

        new MyThread(i).start();
  }
  }

 

上面是实现多线程的一种方式,但是它有个缺点:那就是如果我们的类已经从一个类继承(如小程序必须继承自 Applet 类),则无法再继承 Thread 类,这时如果我们又不想建立一个新的类,应该怎么办呢,只能使用方法二了;

(2).实现 Runnable 接口

  Runnable接口只有一个方法run(),我们声明自己的类实现 Runnable接口并提供这一方法,将我们的线程代码写入其中,就完成了这一部分的任务。但是Runnable接口并没有任何对线程的支持,我们还必须 创建Thread类的实例,这一点通过Thread类的构造函数public Thread(Runnable target);来实现

示例程序:

public class MyThread implements Runnable
  {
  int count= 1, number;
  public MyThread(int num)
  {
  number = num;
  System.out.println("创建线程: "+ number);
  }
  public void run()
  {
  while(true)
  {
  System.out.println
  ("线程 " +number +"  计数: "+ count);
  if( count== 6) return;
  }
  }
  public static void main(String args[])
  {
  for(int i =0; i<5;i++ ) new Thread(new MyThread(i)).start();
  }
  }

使用 Runnable 接口来实现多线程使得我们能够在一个类中包容所有的代码,有利于封装,它的缺点在于,我们只能使用一套代码,若想创建多个线程并使各个线程执行不同的代 码,则仍必须额外创建类,如果这样的话,在大多数情况下也许还不如直接用多个类分别继承 Thread 来得紧凑。

 

3.线程的生命周期

(1)start()方法 启动一个线程

(2)run()方法 定义该线程的动作

(3)sleep()方法 使线程睡眠一段时间,单位为毫秒

(4)suspend()方法 使线程挂起

(5)resume()方法 恢复挂起的线程

(6)yield()方法 把线程移到队列的尾部

(7)stop()方法 结束线程生命周期并执行清理工作

(8)destroy()方法 结束线程生命周期但不做清理工作

  其中最常用的是start(),run(),sleep(),stop()。 

4.线程的四种状态

(1). 新状态:线程已被创建但尚未执行(start() 尚未被调用)。

(2). 可执行状态:线程可以执行,虽然不一定正在执行。CPU 时间随时可能被分配给该线程,从而使得它执行。

(3). 死亡状态:正常情况下 run() 返回使得线程死亡。调用 stop()或 destroy() 亦有同样效果,但是不被推荐,前者会产生异常,后者是强制终止,不会释放锁。

(4). 阻塞状态:线程不会被分配 CPU 时间,无法执行

 

5.线程的优先级

线程的优先级低并不是意味着线程得不到执行,优先级低只是执行的频率比较低吧

你可以调用 Thread 类的方法 getPriority() 和 setPriority()来存取线程的优先级,线程的优先级界于1(MIN_PRIORITY)和10(MAX_PRIORITY)之间,缺省是5(NORM_PRIORITY)。

package MyJava_Base;

class myThread extends Thread

 private String name;
 int priority;
 
 myThread(String name,int priority)
 { 
  this.name=name;
  this.setName(name);
  this.priority=priority;
  this.setPriority(priority);
 }
 public void run()
 { 
 
  System.out.println("线程启动\t名称: "+this.getName()+"\t 优先级: "+this.getPriority());
 }

}

public class testThreadPriority

 public static void main(String[] args)
 { 
  myThread t1=new myThread("A",3);
  myThread t2=new myThread("B",5);
  myThread t3=new myThread("C",9);
  
  t1.start();
  t2.start();
  t3.start();
  
  try
  { 
   t1.join();
   t2.join();
   t3.join();
  }catch(InterruptedException e)
  { 
   System.out.println("Error:"+e);
  }
  
 
 }



 

6.后台线程(守护线程):

守护线程是一类特殊的线程,它和普通线程的区别在于它并不是应用程序的核心部分, 当一个应用程序的所有非守护线程终止运行时,即使仍然有守护线程在运行,应用程序也将终止,反之,只要有一个非守护线程在运行,应用程序就不会终止。守护 线程一般被用于在后台为其它线程提供服务。

  可以通过调用方法 isDaemon() 来判断一个线程是否是守护线程,也可以调用方法 setDaemon() 来将一个线程设为守护线程

posted on 2008-12-01 13:08  NickyYe  阅读(264)  评论(0编辑  收藏  举报