【Java多线程编程核心技术】第一章 Java多线程技能

线程的启动及常用方法

对于线程的启动来说,首先涉及到的就是run()和start()这两个方法。一种方法是继承Thread类,覆盖run方法;一种是实现Runnable接口。

因为开启线程的start方法只在Thread类中存在,所以两种方法都需要借助Thread类中的start()来开启线程。

//在Runable接口中只有一个run方法
public interface Runnable {
    public abstract void run();
}

//Thread类实现了Runnable
public class Thread implements Runnable{    
    
    public synchronized void start() {
        
        //如果多次调用start(),会抛出IllegalThreadStateException异常
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        
		...
    }
    
//由此构造方法可知,还可传入一个Thread对象,
//将一个Thread对象的run()交给其他线程进行调用
public Thread(Runnable target) {
        //...
    }
}


/**
* Tests if this thread is alive. A thread is alive if it has
* been started and has not yet died.
* 线程还未执行完毕
*/
public final native boolean isAlive();

/**
* Returns a reference to the currently executing thread object.
*/
public static native Thread currentThread();


//sleep方法
public static void sleep(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++;
    }

    sleep(millis);
}

public static native void sleep(long millis) throws InterruptedException;


//getId()
private long tid;

private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
    	//...
    
        /* Set thread ID */
        tid = nextThreadID();
    }

/* For generating thread ID 初始化为 0 */
private static long threadSeqNumber;

private static synchronized long nextThreadID() {  return ++threadSeqNumber;  }

public long getId() { return tid; }


// A hint to the scheduler that the current thread is willing to yield
// its current use of a processor. The scheduler is free to ignore this
// hint.
public static native void yield();



如何暂停线程
@Deprecated
public final void suspend() {
    //Determines if the currently running thread has permission to modify this thread.
    checkAccess();
    suspend0();
}
private native void suspend0();


@Deprecated
public final void resume() {
    checkAccess();
    resume0();
}
private native void resume0();

缺点:

  1. 如果使用不当,易造成公共的同步对象的独占,使得其它线程无法访问公共同步对象(线程进入synchronized代码块中被suspend时,不释放锁)
  2. 容易导致数据不同步(在同步块中修改两个属性值,修改完一个后被suspend,然后有其它线程把两个属性值都读取)


如何停止线程

停止线程:在线程处理完任务之前停掉正在做的操作

停止线程的3中方法:

  1. run()完成后线程终止
  2. 使用stop()强行终止线程,可能产生不可预料的结果,该方法已被废弃
    • stop()会在run()中的任何地方抛出ThreadDeath异常来停止线程
    • 这种方式,可能导致持有的锁被突然释放,导致数据的一致性被破坏
    • 可能使一些请理性的工作得不到完成
  3. interrupt()中断线程
    • 该方法仅仅是在当前线程中打了一个interrupt的标志

interrupted()与isInterrupted()
//检测  当前线程  是否是已经中断状态,执行后具有将状态标记清楚为false的功能
public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

//测试  Thread对象  是否已经是中断状态,但不清除状态标志
public boolean isInterrupted() {
    return isInterrupted(false);
}

private native boolean isInterrupted(boolean ClearInterrupted);

能停止线程的方法

interrupt标志的作用:打上标志之后,线程会继续运行,一旦线程进入sleep状态,就会抛异常,停止线程)

  1. 在使用interrupt()之后,检测中断状态,抛出异常来停止线程
    if(this.interrupted()) throw new InterruptedException();
    
  2. 在线程sleep状态下,调用interrupt(),会抛出异常,并清除停止状态值,使之变成false
  3. 先调用interrupt(),然后再让线程进入sleep状态,也会抛出异常
  4. interrupt()与return结合也能停止线程,通过检测线程中断状态
    if(this.interrupted()) return;
    



线程的优先级

CPU优先执行优先级较高的线程对象中的任务

public final static int MIN_PRIORITY = 1;

public final static int NORM_PRIORITY = 5;

public final static int MAX_PRIORITY = 10;


public final void setPriority(int newPriority) {
    ThreadGroup g;
    checkAccess();
    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
        throw new IllegalArgumentException();
    }
    if((g = getThreadGroup()) != null) {
        if (newPriority > g.getMaxPriority()) {
            newPriority = g.getMaxPriority();
        }
        setPriority0(priority = newPriority);
    }
}

private native void setPriority0(int newPriority);

优先级特性:

  1. 继承性:A线程启动B线程,则B线程的优先级与A相同
  2. 规则性:优先级高的大部分先执行完
  3. 随机性:优先级高的不一定每次都先执行完



守护线程

当进程中不存在非守护线程时,守护线程自动销毁(垃圾回收线程就是典型的守护线程)

/* Whether or not the thread is a daemon thread. */
private boolean daemon = false;

public final void setDaemon(boolean on) {
    checkAccess();
    if (isAlive()) {
        throw new IllegalThreadStateException();
    }
    daemon = on;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值