多线程编程核心技术(一)介绍

串行思维是一个很固化的东西,不过也很尴尬的是,处理器最早最早的时候就是串行。你说串行思想肯定是与生俱来的,特别是写代码的时候。能稍微用来一点分治的思维,代码就已经相当的有可读性了。但是多线程这东西肯定是要深刻留在大脑里面的,不然注定面试时候被敲倒。这年头其实说实话,我写代码以来就感觉这个水平是真的参差不齐。特别是随着Java越来越强大,写代码变得更加的容易。大佬封装好了一切,你主需要.api就可以成为一个合格的CRUD工程师,内心对业务了如指掌,基本上就不会被辞退。有人说现在的程序员分成了业务派和技术派。真扯淡。技术饭永远以技术为主。公司需要自己的技术护城河,同样的程序员也应该有自己的技术护城河

这一章是写Thread类的核心方法,线程的启动,如何使线程停止,如何使线程暂停,线程的优先级,线程安全相关问题。

线程是进程中的子任务,一个线程就是一个任务可以这么累计,左手吃饭,右手看手机,人是一个进程。

多线程的意思就是有限时间内发挥CPU的最大性能。以前有个朋友和我说最好服务器上的CPU永远保持在80-95%之间是最好的。现在想想平滑的业务情况下,100%都没问题。

 

 如果CPU的能力可以在任务一和任务二之间来回切换,那么第二种情况是最好的。多线程是一个异步的,至少在逻辑上是异步的。

首先得到一个线程的类,感受下什么是线程


public class demo4   {

public void run(){
int j = 0;
for (int i = 0; i < 1000000; i++) {
j +=i;
}
}

public void l(){
int j = 0;
for (int i = 0; i < 1000000; i++) {
j +=i;
}
}

public static void main(String[] args) {
demo4 demo4 = new demo4();
long a = System.currentTimeMillis();
demo4.run();
System.out.println(System.currentTimeMillis()-a);
demo4.l();
System.out.println(System.currentTimeMillis()-a);
}
}

输出为:
3
6

加上多线程之后
public class demo4 extends Thread {
@Override
public void run(){
int j = 0;
for (int i = 0; i < 1000000; i++) {
j +=i;
}
}

public void l(){
int j = 0;
for (int i = 0; i < 1000000; i++) {
j +=i;
}
}

public static void main(String[] args) {
demo4 demo4 = new demo4();
long a = System.currentTimeMillis();
demo4.start();
System.out.println(System.currentTimeMillis()-a);
demo4.l();
System.out.println(System.currentTimeMillis()-a);
}
}
输出为:
0
3

 这边要注意的就是就算是多线程情况下,也一定要使用.start(),如何是.run()还是无效的。

 

start方法
public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); boolean started = false; try {
//真正的执行方法是这个,上面的都是check的过程。start0是一个本地方法,调用的不是java。 start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { it will be passed up the call stack */ } } }

run方法
@Override
public void run() {
if (target != null) {
target.run();
}
}

  那么为什么要使用.start而不是,run呢?看上面的源码好像没有发现start和run之间的关系。run()只是接口中的一个方法,如果没有实现就无效。猜想下8成概率是和start0()方法有关系的。

start0()方法是一个C实现的方法,run()不是开启新线程的钥匙,但是start()中的新线程会去调用这个重写的run()方法。也就是逻辑上应该是start()-->start0()-->JVM-->run()

回忆下,静态方法,是什么时候被加载的,类加载的时候静态方法就也诞生了,start0方法对应在具体代码是下面这个。

{"start0", "()V",(void *)&JVM_StartThread}, 然后执行了JVM_StartThread。JVM又会去创建一个新的JavaThread,到这算是真正的创建出了线程。这个新线程再调用方法,最后轮到 template(run_method_name,"run") 方法。总体有点乱,逻辑上就是

JNIEXPORT void JNICALL 
 Java_Java_lang_Thread_registerNatives (JNIEnv *env, jclass cls){ 
   (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods)); 
 } 
 static JNINativeMethod methods[] = { 
    {"start0", "()V",(void *)&JVM_StartThread}, 
    {"stop0", "(" OBJ ")V", (void *)&JVM_StopThread}, 
	 {"isAlive","()Z",(void *)&JVM_IsThreadAlive}, 
	 {"suspend0","()V",(void *)&JVM_SuspendThread}, 
	 {"resume0","()V",(void *)&JVM_ResumeThread}, 
	 {"setPriority0","(I)V",(void *)&JVM_SetThreadPriority}, 
	 {"yield", "()V",(void *)&JVM_Yield}, 
	 {"sleep","(J)V",(void *)&JVM_Sleep}, 
	 {"currentThread","()" THD,(void *)&JVM_CurrentThread}, 
	 {"countStackFrames","()I",(void *)&JVM_CountStackFrames}, 
	 {"interrupt0","()V",(void *)&JVM_Interrupt}, 
	 {"isInterrupted","(Z)Z",(void *)&JVM_IsInterrupted}, 
	 {"holdsLock","(" OBJ ")Z",(void *)&JVM_HoldsLock}, 
	 {"getThreads","()[" THD,(void *)&JVM_GetAllThreads}, 
	 {"dumpThreads","([" THD ")[[" STE, (void *)&JVM_DumpThreads}, 
 };


JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) 
	native_thread = new JavaThread(&thread_entry, sz); 


static void thread_entry(JavaThread* thread, TRAPS) { 
    HandleMark hm(THREAD); 
	 Handle obj(THREAD, thread->threadObj()); 
	 JavaValue result(T_VOID); 
	 JavaCalls::call_virtual(&result,obj, 
	 KlassHandle(THREAD,SystemDictionary::Thread_klass()), 
	 vmSymbolHandles::run_method_name(), 
 vmSymbolHandles::void_method_signature(),THREAD); 
 }


class vmSymbolHandles: AllStatic { 
	template(run_method_name,"run") 
	}
 

 

那么线程在硬件眼里是个怎么样的存在?如果调用的呢?

我认为多线程的正确含义应该是单位时间内多个线程串行处理。如果把CPU看到最简单的一个逻辑门,那它的功能就仅仅只是进行信号的处理。一个线程分化多个任务进入逻辑门,例如加减,IO,加减,IO,加加。如果是单线程的的情况下就是这一个线程相当于一定会执行完,多线程的情况下就是IO的时候,可以再进行另外线程的任务,不让CPU休息。逻辑上单核处理器,也是具有多线程的能力的。

 

posted @ 2020-12-25 09:19  smartcat994  阅读(189)  评论(0编辑  收藏  举报