Java多线程编程

                                     线程的创建与生命周期

一、线程的类型

    主线程:每个Java应用程序都有一个缺省的主线程。Java应用程序总是从主类的main方法开始执行。当JVM加载代码,发现main方法之后,就会启动一个线程,这个线程称为”主线程“(main线程),该线程负责执行main方法。

    其他线程:在main方法执行过程中创建的的线程就称为其他线程称。

    二者关联:main方法即使执行完最后的语句,JVM也不会结束java应用程序,JVM一直要等到java应用程序中的所有的进程运行结束后,才终止java应用程序。

二、线程的创建

  有两种方法可以创建线程。

    1、通过继承类“Thread”来创建线程类。如:

   class aaa extends Thread { //aaa 是类的名称

  public void run() { //run 是整个线程类代码的入口, 与C 语言中的main 类似

  // 源程序

   }

  }

  2、建立一个具有Runnable 接口的类。如:

  class aaa implements Runnable { //aaa 是类的名称

   public void run() {  //run 是整个线程类代码的入口, 与C 语言中的main 类似

  // 源程序

   }

  }

三、线程的调用

  如果采用第一种方法,创建的线程类的调用格式如下:

  aaa test=new aaa();//test 是线程类aaa 的一个实例

   test.start();

  //start 是线程类的成员函数,将产生一

  // 个新的线程,这个线程自动调用run

  如果采用第二种方法,创建的线程类的调用格式如下:

  aaa test=new aaa();

  //test 是类aaa 的一个实例

  new Thread(test).start();

  // 通过Thread 创建

  // 一个新的线程

四、线程类的变量及成员函数

  变量: 

    MAX_PRIORITY 规定了线程优先级所能设置的最大值 
  MIN_PRIORITY 规定了线程优先级所能设置的最小值 
  NORM_PRIORITY 线程优先级的缺省值成员函数: 
  activeCount() 返回该线程组中当前激活的线程的数目 
  checkAccess() 检测当前线程是否可以被修改 
  countStackFrames() 返回该线程的堆栈框的数目 
  currentThread() 返回当前正在执行的线程对象 
  destroy() 终止一个线程,不清除其他相关内容 
  dumpStack() 一个调试过程,输出当前线程的堆栈使用情况 
  enumerate(Thread[]) 将所有该线程组中激活的线程复制到一个特殊的数组中 
  getName() 返回线程的名称 
  getPriority() 返回线程的优先级 
  getTheradGroup() 返回线程组 
  interrupt() 向一个线程发送一个中断信息 
  interrupted() 检查该线程是否被中断 
  isAlive() 检查线程是否处于激活状态 
  isDaemon() 检查该线程是否常驻内存 
  isInterrupted() 检查另一个线程是否被中断 
  join(long) 在long 毫秒中等待线程中止 
  join(long,int) 在long 毫秒int 纳秒内等待线程中止 
  join() 永远等待线程的中止 
  resume() 重新开始执行该线程 
  run() 整个代码的入口与C 语言中的main 类似 
  setDaemon() 将该线程设置为Daemon( 常驻内存) 
  setName(String) 设置线程的名称 
  setPriority(int) 设置线程的优先级 
  sleep(long) 使一个线程休眠long 毫秒 
  sleep(long,int) 使一个线程休眠long 毫秒int 纳秒 

        wait()是当前线程处于等待状态

        notify()通知一个处于等待状态的线

        notifyAll()通知所有处于等待状态的线程

  start()启动一个线程,这个线程将自动调用run 函数。同时,在新的线程开始执行时,调用start 的的那个线程将立即返回执行主程序stop() 终止一个线程

  stop(Throwable) 终止一个线程,该线程是由Throwable 类继承过来的 
  suspend() 暂停线程的执行 
  toString() 返回一个字符串,包括线程的名称、优先级和线程组 
  yield() 使线程放弃对CPU 的控制,使其它处于等待状态的线程运行 

    注意:线程一旦执行了sleep(int millsecond)方法后,该线程立刻让出CPU的使用权,当前线程处于中断状态,经过指定的时间后,该线程就重新进到线程队列中等待CPU资源,以便从中断处继续执行。而执行wait()方法后,必须由其他线程调用notify()方法通知,使得它重新进到CPU等待队列中,否则它将一直等待。

五、同步设定

  当两个函数需要使用同一个资源时,不能同时执行。JAVA 提供了同步设定的功能。每个类对自己代码中不能与其它程序同时运行的部分进行同步设定。同步设定的功能是通知JAVA 哪些代码段已被加锁而只能单独运行。有以下两种方法进行同步设定:

  1、将函数设置为同步方式

  public synchronized void fun1() {

  // 源代码

  }

  public synchronized void fun2() {

  // 源代码

  }

  对于上述被设置为同步方式的函数,只有在获得资源后,方可运行。对于每一个类来说,只有一个资源。任何时刻都只有一个获得资源的程序在运行,函数在获得资源前处于等待状态。

  2、在调用函数中说明此函数需要被同步

  synchronized(res) {

  res.fun1();

  }

  synchronized(res) {

  res.fun2();

  }

  在上述例子中,fun1 与fun2 只能获得res 的资源后才能运行。函数调用结束后,资源才被释放,从而使其它等待这个资源的线程得以运行。

六、线程联合

    一个线程A在占有占有CPU资源期间,可以让其他线程调用join()和本线程联合,如B.join();我们称A在运行期间联合了线程B。如果线程A在占有CPU资源期间一旦联合线程B,那么A将立刻中断执行,知道线程B执行完毕,A线程再重新排队等待CPU资源,以便恢复。如果A准备联合的B线程已结束,那么B.join不会有任何效果。

七、线程变量的安全

  可以把线程中的变量设置为安全的,这将使该线程使用这个变量时其它线程不能改变这个变量的值。这个功能使用编译器更易于实现代码优化。如果不使用这种设置,编译器很难将一个线程中已被修改的变量区别开来。这种安全变量的定义方式如下:

  threadsafe int ttt;       //threadsafe 是线程安全变量的类型,ttt 是变量名

  常用的static 变量就是线程安全变量的典型例子。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值