java.lang.Thread

本文详细介绍了Java中多线程的基础知识,包括线程的创建、生命周期、优先级设定及同步机制等内容。此外,还解释了如何使用Runnable接口或继承Thread类来实现线程,并探讨了线程间的同步和中断处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package java.lang;

import java.security.AccessController;
import java.security.AccessControlContext;
import java.util.Map;
import java.util.Collections;

import sun.nio.ch.Interruptible;
import sun.security.util.SecurityConstants;


/**
 *
 * java支持多线程,Thread对象用于表示一个线程,但是它与线程是两个概念
 *
 * 与线程有关的类(接口)包括(Thread,Runnable,ThreadGroup,ThreadLocal,Object,ThreadDeath)
 * 线程通过一个int型值表示其优先级,优先级大的则更有机会优先处理(注意不是优先级大的就一定会比优先级
 * 低的先得到处理,不能以此作为编程的依赖,优先级大只是表示会优先处理的机率大),创建一个线程会将
 * 其优先级默认置为创建此线程的优先级
 *
 *
 * 原始的线程是一个非daemon的main线程,他是是JVM运行的起始,由它来创建新线程,
 * 再由新创建的线程在创建线程,如此往复,
 * 一个简单的类的main方法的调用过程是,jvm产生一个main线程(和对应的main,System线程组,main
 * 线程在main线程组中,main线程组的父线程组是System线程组,可以在eclipse的debug模式下看到),
 * 由main线程调用此对象的main方法
 * 一个服务器的实现也是由调用main方法启动一个main线程线程,
 * 在此线程中做循环,或由它创建的线程做循环操作,来实现服务的功能,
 *
 * JVM停止运行进程是由于以下情况
 * 1 调用了Runtime.exit()方法(停止虚拟机)
 * 2 所有非Deman的线程都已经died(执行结束)
 * 3 从run方法中抛出异常
 *
 * 静态方法是对当前线程操作
 *
 *
 * 使用线程的两种方式,继承此线程,或实现Runnable接口,实现接口的方式更灵活,因为此线程
 * 类的父类可以是其他类
 * 使用线程的两种方法:
class tt1 extends Thread {
  public void run() {
   System.out.println("test1");
     }
}

Thread t1 = new tt1();  
t1.start();


class kk {}

class tt2 extends kk implements Runnable {
 public void run() {}
}

Thread t2 = new Thread(new tt2());
t2.start();
 *
 * 线程有4中状态,
 * 1 初始状态(new 一个Thread对象,但没有调用start方法)
 * 2 活动状态,线程正在运行(注意,多个没有共享数据的线程可以同时运行,而
 * 有同步操作的线程,只能有一个运行,其他处于挂起状态)
 * 3 挂起状态,由于调用了waite,join,sleep而使线程挂起,线程只有在超时,唤醒,
 * interrupt的情况(必须要catch异常,不让线程将终止)下才会重新获得,
 * 注意活动状态和挂起状态都表示Alive
 * 4 线程终结状态(die),正确运行结束,,或由于异常而是线程die
 *
 * 正确结束是应为:
 * 1无循环的简单操作,
 * 2有循环但循环标记(因为线程不提倡使用stop,则使用一个标记
 * 表示此线程结束,它实际是是循环结束)变为不再循环
 * 3wait的线程被notify,或到时,或被interrupt,sleep的线程
 * 到时或被interrupt,join的线程到时,或被interrupt
 *
 * 实现同步的几种形式
 * 1 synchronized一个方法,synchronized(this) {...}
 * 表示对当前对象加锁,此对象会被多个进程使用(进程会有此对象的句柄,可能是从构造函数
 * 将此对象传入到线程,也可能是通过类似set的方法),它保护的是当前对象中的所有数据
 *
 * 2 Object someObj = new Object();
 *   synchronized(someObj){...}
 * 表示对一个对象加锁,我们关心的是对象中的数据,保护区中使用
 * 了此对象的数据,但是是安全的,不同线程用此对象的地方要使用
 * synchronized不然起不到保护作用
 *
 * 3 synchronized一个对象锁,
 * Object lock = new Object();
 * synchronized(lock){...}
 * 使用对象锁将所住一个块,此块中都是线程安全的,这里
 * 我们不关心lock中的数据,仅是使用它锁定了一个区域,
 * 这个区域可以包括多个对象
 *
 * 4 使用waite和notify来达到某种条件下才能访问的区域.
 * 调用wait或notify之前都会有一个条件判断,这个判断依据的数据
 * 可能是来源于锁定对象,也可能是来自其他一组对象(这时把锁定对象当作一个锁对象看待)
 * 通过这组对象计算出一个条件,不满足此条件线程被wait,
 * 而另一个进程通过这组对象计算出的条件成立则改变了这组对象的状态,
 * 并调用了notify,这时我们保证了代码在符合的条件下执行
 *
 * 有线程A,B对对象Obj有同步访问当条件不满足时,
 * 线程A调用obj的waite方法,则接下去的区域
 * 不可被访问,这就起到了保护的作用,而线程B做一些操作,
 *
 * comment by liqiang
 *
 */
public
class Thread implements Runnable {
    private static native void registerNatives();
    static {
        registerNatives();
    }

    //表示线程名的char数组
    private char name[];
    //优先级
    private int         priority;
    private Thread threadQ;
    private long eetop;

    private boolean single_step;

    //此线程是否是守护线程
    private boolean daemon = false;

    private boolean stillborn = false;

    //如果使用Runnable接口方式使用线程,它表示线程实现的内容
    private Runnable target;

    //线程所在的线程组
    private ThreadGroup group;

    private ClassLoader contextClassLoader;

    private AccessControlContext inheritedAccessControlContext;

    //给未命名线程生成名称时用的数字变量
    private static int threadInitNumber;
    //产生给未命名线程生成名称时用的数字变量
    private static synchronized int nextThreadNum() {
 return threadInitNumber++;
    }

    //用户存发此线程的ThreadLocal对象
    ThreadLocal.ThreadLocalMap threadLocals = null;

    //用于存放此线程的inheritable行的ThreadLocal对象
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

    private long stackSize;

    private volatile Interruptible blocker;

    private void blockedOn(Interruptible b) {
 blocker = b;
    }

    /**
     * 最小优先级
     */
    public final static int MIN_PRIORITY = 1;

   /**
     * 普通优先级
     */
    public final static int NORM_PRIORITY = 5;

    /**
     * 最大优先级
     */
    public final static int MAX_PRIORITY = 10;

    //获得当前运行线程的线程对象
    public static native Thread currentThread();

    /**
     * 使当前执行线程挂起
     */
    public static native void yield();

    /** 
     *
     * 使当前线程停止运行指定毫秒数,达到时限或被其他线程中断(interrupt)则线程继续运行
     * 注意线程sleep了并不释放任何它所拥有的锁
     *
     */
    public static native void sleep(long millis) throws InterruptedException;

    /**
     * 使当前线程sleep指定时间,含有微妙精度
     *
     * @param      millis   等待 毫秒数(千分之一秒)
     * @param      nanos    微秒数(十亿分之一秒),范围在0-999999
     */
    public static void sleep(long millis, int nanos)
    throws InterruptedException {
    //毫秒数为负抛出异常
 if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
 }

 //微秒数在0-999999范围内,不符则抛出异常
 if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
    "nanosecond timeout value out of range");
 }

 //进位
 if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
     millis++;
 }

 sleep(millis);
    }

    /**
     * 初始化一个线程
     *
     * @param g 初始化的线程所在的线程组
     * @param target Runnable对象
     * @param name 新线程的名字
     * @param stackSize 线程的栈长度,0表示忽视
     */
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
    //父线程为当前线程程
 Thread parent = currentThread();
 if (g == null) {
  //安全处理
     SecurityManager security = System.getSecurityManager();    
     if (security != null) {
  g = security.getThreadGroup();
     }

     //如果没有线程组,则使用父线程组
     if (g == null) {
  g = parent.getThreadGroup();
     }
 }

 //安全检查
 g.checkAccess();    

 //设置状态
 this.group = g;
 this.daemon = parent.isDaemon();
 this.priority = parent.getPriority();
 this.name = name.toCharArray();
 this.contextClassLoader = parent.contextClassLoader; 
 this.inheritedAccessControlContext = AccessController.getContext();
 //设置Runnable对象
 this.target = target;
 
 //设置优先级
 setPriority(priority);
 
  //通过父线程的inheritable的ThreadLocalMap,和它的childValue方法
  //创建当前线程的inheritable的ThreadLocalMap
        if (parent.inheritableThreadLocals != null)
          this.inheritableThreadLocals =
            ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);

        this.stackSize = stackSize;
   
    //将此线程对象加入到其所在的线程组
 g.add(this);
    }

    /**
     * 生成一个线程,线程名自动生成
     *
     */
    public Thread() {
    //自动生成一个线程名,并使用他初始化
 init(null, null, "Thread-" + nextThreadNum(), 0);
    }

    /**
     * 线程的构造函数,线程名自动生成,target表示线程运行的内容   
     */
    public Thread(Runnable target) {
 init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    /**
     * 线程的构造函数
     */
    public Thread(ThreadGroup group, Runnable target) {
 init(group, target, "Thread-" + nextThreadNum(), 0);
    }

    /**
     * 线程的构造函数
     */
    public Thread(String name) {
 init(null, null, name, 0);
    }

    /**
     * 线程的构造函数
     */
    public Thread(ThreadGroup group, String name) {
 init(group, null, name, 0);
    }

    /**
     * 线程的构造函数
     */
    public Thread(Runnable target, String name) {
 init(null, target, name, 0);
    }

    /**
     * 线程的构造函数
     */
    public Thread(ThreadGroup group, Runnable target, String name) {
 init(group, target, name, 0);
    }

    /**
     * 线程的构造函数
     */
    public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
 init(group, target, name, stackSize);
    }

    /**
     * 启动线程,线程运行的内容在run方法中实现,run方法是由虚拟机调用的
     *
     */
    public synchronized native void start();

    /**
     * 线程运行的实际内容定义的位置,如果继承此线程,需要重写此方法
     * 将运行内容写在此位置,如果使用接口,则此方法默认调用接口的
     * run方法
     */
    public void run() {
 if (target != null) {
     target.run();
 }
    }

    /**
     * 由虚拟机调用,保证线程退出前的清理工作
     */
    private void exit() {
 if (group != null) {
     group.remove(this);
     group = null;
 }
 
 target = null;
    }

    /**
     *
     * 停止线程,此方法会产生死锁不建议使用
     *
     * @deprecated
     *
     */
    public final void stop() {
 synchronized (this) {
            //如果线程不是Alive的之际返回
            if (!this.isAlive()) return;
     SecurityManager security = System.getSecurityManager();
     if (security != null) {
  checkAccess();
  if (this != Thread.currentThread()) {
      security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
  }
     }
    
     //如果线程挂起,则唤醒它
     resume();
    
     stop0(new ThreadDeath());
 }
    }

    /**
     * 停止线程,此方法会产生死锁不建议使用
     *
     * @deprecated
     *
     */
    public final synchronized void stop(Throwable obj) {
 SecurityManager security = System.getSecurityManager();
 if (security != null) {
     checkAccess();
     if ((this != Thread.currentThread()) ||
  (!(obj instanceof ThreadDeath))) {
  security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
     }
 }
 
 //如果线程挂起,则唤醒它
 resume();
 stop0(obj);
    }

    /**
     *
     * 中断此线程
     * 如果线程被waite,sleep,join方法阻断,另一线程调用此线程对象的interrupt方法
     * 则此线程中断标志被清空,此线程抛出 InterruptedException
     *
     * 如果线程被I/O操作阻断,另一线程调用此线程对象的interrupt方法
     * 则此线程中断标志被设置,此线程抛出 InterruptedException
     *
     * 如果线程没有被阻断,则此线程的中断标志被设置
     *
     */
    public void interrupt() {
 checkAccess();
 
 Interruptible b = blocker;
 
 if (b != null) {
     b.interrupt();
 }
 
 //本地方法
 interrupt0();
    }

    /**
     *
     * 判断当前线程的中断状态,并清空中断状态(先返回状态,再做清空操作)
     *
     * @return  true表示当前当前是中断状态,false表示不是
     *
     */
    public static boolean interrupted() {
 return currentThread().isInterrupted(true);
    }

    /**
     *
     * 判断线程的中断状态,不影响线程的中断状态
     *
     */
    public boolean isInterrupted() {
 return isInterrupted(false);
    }

    /**
     *
     * 判断线程的中断状态的本地方法,ClearInterrupted表示是否清空状态
     *
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

    //销毁线程,此方法没有实现
    public void destroy() {
 throw new NoSuchMethodError();
    }

    //判断线程是否Alive
    public final native boolean isAlive();

    /**
     *
     * 挂起线程,不建议被使用
     *
     * @deprecated
     */
    public final void suspend() {
 checkAccess();
 suspend0();
    }

    /**
     *
     * 使挂起的线程重新运行,因为会产生死锁此方法不建议使用
     *
     * @deprecated
     *
     */
    public final void resume() {
    //安全检查
 checkAccess();
 //调用恢复此线程的本地方法
 resume0();
    }

    /**
     *
     * 设置优先级
     *
     */
    public final void setPriority(int newPriority) {
    //安全检查
 checkAccess();
 //优先级超出范围,抛出异常
 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
     throw new IllegalArgumentException();
 }
 
 //如果优先级超出所在线程组的最大优先级,则使用线程组的最大优先级
 if (newPriority > group.getMaxPriority()) {
     newPriority = group.getMaxPriority();
 }
 
 //设置当前优先级变量,并调用本地方法,设置线程的优先级
 setPriority0(priority = newPriority);
    }

    /**
     *
     * 返回优先级
     *
     */
    public final int getPriority() {
 return priority;
    }

    /**
     *
     * 设置线程名
     *
     */
    public final void setName(String name) {
 checkAccess();
 this.name = name.toCharArray();
    }

    /**
     *
     * 返回线程名
     *
     */
    public final String getName() {
 return String.valueOf(name);
    }

    /**
     *
     * 获得此线程的线程组对象
     *
     */
    public final ThreadGroup getThreadGroup() {
 return group;
    }

    /**
     *
     * 获得此线程所在线程组中Alive的线程
     *
     */
    public static int activeCount() {
 return currentThread().getThreadGroup().activeCount();
    }

    /**
     *
     * 将当前线程组,和子组(此线程组中包含线程组,和其下的子线程组)
     * 中的Alive的线程对象拷贝到线程数组中
     *
     */
    public static int enumerate(Thread tarray[]) {
 return currentThread().getThreadGroup().enumerate(tarray);
    }

    /**
     *
     * 获得此线程的栈帧数,此舷窗那嘎必须处于挂起状态,如果不出于挂起状态
     * 则抛出IllegalThreadStateException,此方法不建议被使用
     *
     * @deprecated
     *
     */
    public native int countStackFrames();

    /**
     *
     * 某一线程A调用另一个线程对象B的join方法
     * 挂起线程A直到指定时间,或B线程死掉,
     * millis为0表示永远等待
     *
     */
    public final synchronized void join(long millis)
    throws InterruptedException {
     
    //表示起始时间 
 long base = System.currentTimeMillis();
 long now = 0;

 if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
 }

 if (millis == 0) {
     while (isAlive()) {
  wait(0);
     }
 } else {
     while (isAlive()) {
     //表示还剩多少时间需要等待,计算方式是一共等待的时间减去等待了的时间
  long delay = millis - now;
  if (delay <= 0) {//已经达到或超过等待时间退出
      break;
  }
  
  //会让此线程对象的join方法的线程挂起
  wait(delay);
  
  //算出两个时间差,表示已经消耗了多少时间,
  now = System.currentTimeMillis() - base;
     }
 }
    }

    /**
     * 某一线程A调用另一个线程对象B的join方法
     * 挂起线程A直到指定时间,或B线程死掉
     * millis的计算值为0(millis为0且nanos为0)时表示永远等待
     */
    public final synchronized void join(long millis, int nanos)
    throws InterruptedException {

 if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
 }

 if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
    "nanosecond timeout value out of range");
 }

 if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
     millis++;
 }

 join(millis);
    }

    /**
     * 某一线程A调用另一个线程对象B的join方法
     * 挂起线程A直到B线程死掉
     *
     */
    public final void join() throws InterruptedException {
 join(0);
    }

    /**
     *
     * 打印出出当前线程的调用栈,此方法是为调试使用
     *
     */
    public static void dumpStack() {
 new Exception("Stack trace").printStackTrace();
    }

    /**
     *
     * 设置线程的Daemon状态
     * 调用此方法是,线程不能为Alive状态,
     * 应在生成线程对象,没有调用start方法前调用此方法
     *
     * @param  on true表示守护线程,false表示 用户线程  
     */
    public final void setDaemon(boolean on) {
 checkAccess();
 
 //如果是Alive状态则抛出异常
 if (isAlive()) {
     throw new IllegalThreadStateException();
 }
 
 //设置daemon状态
 daemon = on;
    }

    /**
     *
     * 返回线程的Daemon状态
     *
     */
    public final boolean isDaemon() {
 return daemon;
    }

    //判断当前线程,是否有修改当前线程的权限
    public final void checkAccess() {
 SecurityManager security = System.getSecurityManager();
 if (security != null) {
     security.checkAccess(this);
 }
    }

    /**
     *
     * 返回字符串表示
     *
     */
    public String toString() {
        ThreadGroup group = getThreadGroup();
 if (group != null) {
     return "Thread[" + getName() + "," + getPriority() + "," +
             group.getName() + "]";
 } else {
     return "Thread[" + getName() + "," + getPriority() + "," +
              "" + "]";
 }
    }

    /**   
     *
     * 返回contextClassLoader
     * contextClassLoader对象用于线程加载类或资源,如果它没有被设置,将
     * 默认设为父线程的contextClassLoader对象,初始线程的contextClassLoader
     * 对象是转载启动类的ClassLoader
     *
     */
    public ClassLoader getContextClassLoader() {
 if (contextClassLoader == null)
     return null;
 SecurityManager sm = System.getSecurityManager();
 
 if (sm != null) {
     ClassLoader ccl = ClassLoader.getCallerClassLoader();
     if (ccl != null && ccl != contextClassLoader &&
                    !contextClassLoader.isAncestor(ccl)) {
  sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
     }
 }
 
 return contextClassLoader;
    }

    /**  
     *
     * 设置contextClassLoader对象
     *
     */
    public void setContextClassLoader(ClassLoader cl) {
 SecurityManager sm = System.getSecurityManager();
 if (sm != null) {
     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
 }
 contextClassLoader = cl;
    }

    /**
     *
     * 判断当前线程是否有指定对象的锁
     *
     * @param  obj 当前对象是否有此对象上上的锁
     * @throws NullPointerException obj为null是抛出
     */
    public static native boolean holdsLock(Object obj);

    //设置优先级的本地方法
    private native void setPriority0(int newPriority);
    //停止线程的本地方法
    private native void stop0(Object o);
    private native void suspend0();
    //使挂起的线程重新运行
    private native void resume0();
    //中断线程的本地方法
    private native void interrupt0();
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值