一:執行緒與程式的概念
程式(Process) 是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統結構的基礎。 在當代面向執行緒設計的計算機結構中,程式是執行緒的容器。程式是指令、資料及其組織形式的描述,程式是程式的實體
執行緒(thread) 是作業系統能夠進行運算排程的最小單位。它被包含在程式之中,是程式中的實際運作單位。一條執行緒指的是程式中一個單一順序的控制流,一個程式中可以併發多個執行緒,每條執行緒並行執行不同的任務。
總結:
程式:指在系統中正在執行的一個應用程式;程式一旦執行就是程式;程式——資源分配的最小單位。
執行緒:系統分配處理器時間資源的基本單元,或者說程式之內獨立執行的一個單元執行流。執行緒——程式執行的最小單位。
二:使用程式的兩種方法以及原始碼解析
1.整合Thread類
public class ThreadEx extends Thread{
public void run(){
System.out.println(Thread.currentThread().getName());
}
}
啟動程式碼:
ThreadEx extendThread = new ThreadEx();
extendThread.start();
2.實現Runnable介面
class ThreadIm implements Runnable {
private int currentIndex = 0;
@Override
public void run() {
currentIndex += 1
System.out.println(Thread.currentThread().getName() + ":" + ++currentIndex);
}
}
ThreadIm implementsThread = new ThreadIm();
Thread thread1 = new Thread(implementsThread);
Thread thread2 = new Thread(implementsThread);
thread1.start();
thread2.start();
結果:
Thread-2:2
Thread-1:2
這裡有一個很有意思的問題: 就是同樣一個執行緒例項 被執行多次 那麼 他的屬性 就是非執行緒安全的了
3.Thread原始碼
屬性:
native表示是由著C++封裝的底層方法
private static native void registerNatives();
static {
registerNatives();
}
private volatile char name[];
private int priority;
/* Whether or not the thread is a daemon thread. */
private boolean daemon = false; //是否是守護執行緒
/* What will be run. 執行的執行緒*/
private Runnable target;
/* The group of this thread 執行緒組別*/
private ThreadGroup group;
/* The context ClassLoader for this thread 載入器*/
private ClassLoader contextClassLoader;
/* For autonumbering anonymous threads. */
private static int threadInitNumber; //執行緒初始化數字 每次執行都會+1 用以初始化名字以及標記
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class. 是否是可繼承的ThreadLocal
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
/* Thread ID :tidy = ++threadSeqNumber */
private long tid;
/* For generating thread ID */
private static long threadSeqNumber;
/* Java thread status for tools,
* initialized to indicate thread 'not yet started'
*/
private volatile int threadStatus = 0;
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
/**
* The argument supplied to the current call to
* java.util.concurrent.locks.LockSupport.park.
* Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
* Accessed using java.util.concurrent.locks.LockSupport.getBlocker
*/
volatile Object parkBlocker;
/* The object in which this thread is blocked in an interruptible I/O
* operation, if any. The blocker's interrupt method should be invoked
* after setting this thread's interrupt status.
*/
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
構造方法:
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc);
}
public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0);
}
public Thread(String name) {
init(null, null, name, 0);
}
等等,大致上來說在構造的時候一定會呼叫初始化方法 然後給執行緒中的某些屬性賦值
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name.toCharArray(); //名字初始化
Thread parent = currentThread(); //得到當前執行緒的父執行緒
SecurityManager security = System.getSecurityManager(); //安全管理器是一個允許應用程式實現安全策略的類
if (g == null) { //組別為空 則使用父親的組別
if (security != null) {
g = security.getThreadGroup();
}
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
/*
* Do we have the required permissions?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
acc != null ? acc : AccessController.getContext();
this.target = target;
setPriority(priority);
if (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
start啟動犯法
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0(); //底層方法
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}