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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_37378518/article/details/85122409

线程的启动及常用方法

对于线程的启动来说,首先涉及到的就是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 */
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()之后,检测中断状态,抛出异常来停止线程
  2. 在线程sleep状态下,调用interrupt(),会抛出异常,并清除停止状态值,使之变成false
  3. 先调用interrupt(),然后再让线程进入sleep状态,也会抛出异常
  4. interrupt()与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;
}

猜你喜欢

转载自blog.csdn.net/baidu_37378518/article/details/85122409