深刻理解并发编程 -- 多线程(一)

并发编程 -- 多线程(一)

做者 : Stanley 罗昊java

转载请注明出处和署名,谢谢!linux

进程

在理解多线程以前,咱们先须要了解什么是进程?编程

进程说白了就是在你的内存空间中开辟出的一个独立的空间;windows

若是还不理解的话,我再解释一下;多线程

想必各位以前都安装过软件吧,你安装完软件以后,在你的软件安装包里面是否是有一个.exe文件,那你双击exe文件的时候,在你的任务管理器,在里面就有一个进程选项卡,就是说,每当你打开一个exe文件的时候,它都会显示在任务管理器的进程当中,因此就能够把运行中的任意一款软件,均可以把它看作一个进程;并发

固然,以上的操做方式是在windows系统的操做的,也就是说,想查看Windows的进程,只须要在任务管理器中查看便可;测试

在linux下使用命令 ps 或 pstree、ps -eflgrep;spa

若是想在linux系统下查看java的相关进程,命令为:jps;操作系统

那么问题就来了,当你打开QQ的时候,是否是就是开启了一个进程,当你开始使用它而且聊天的时候,好比你是a,你如今要跟b聊自然后再去跟c聊天,那么这样的操做是否是相互独立的呢?也就是说,你如今要跟b发送你的游戏密码,这个时候c问你晚上吃啥饭,你发的密码c知道吗?确定不会啦,因此你跟b聊天的时候,是不会影响你跟c聊天的,由于你跟b c 是相互独立的线程

那么,在这个里面,你跟他们每一个人产生的通话底层是怎么实现的呢?

底层就是靠线程去实现的;

线程

什么是线程呢?

线程是指程序在执行过程当中,可以执行程序代码的一个执行单元,在Java语言中,线程有四种状态:运行,就绪,挂起,结束。通常状况下,一个操做系统是有多个进程,那么每一个进程都要对应多个线程;

线程与进程有区别吗?

,进程是一段正在运行的程序,而线程有时也被称为轻量级进程,它是进程的执行单元,一个进程能够拥有多个线程,各个线程之间共享程序的内存空间,可是,各个线程拥有本身的栈空间。

一个进程能够有不少线程,每条线程并行执行不一样的任务;

实现单个线程

在以前的一些简单的java练习中,咱们运行的时候,是否是都是在main方法中测试运行啊,那么,在这以前,我仅仅编写了一些很是简单的java代码,甚至就在main方法中输出了一句话,就能够直接完成运行,在这期间,我并无建立有关线程方面的方法以及程序,那么就怎么实现运行了呢?

其实很简单,Main方法既然能运行你的程序,那么必然就会有一个线程,那么这个线程就是单线程,那,咱们如何查看本次运行线程的线程名呢?

咱们仅需在main方法里面输出如下便可:

System.out.println(Thread.currentThread());

打印出来后,咱们就能够看到线程名师Main,由于就一个线程,因此main就是主线程;

那么就一个线程,就代表,在这以前,咱们所作的一些练习程序都是单线程的;

线程的建立方式

两种:

1.继承(extends) Thread

继承完Thread类以后须要重写run方法;

2.实现(implem) Runnable接口

也许须要重写run方法;

继承Thread类建立线程

讲了那么多,那么就开始上手实操一下,咱们将要练习的是继承Thread来建立一个线程;

首先,咱们建立一个类(MyThread)而后继承Thread类;

继承完Thread后,实现run方法;

run方法的做用就是,至关于这个线程对用户提供的一个接口;

因此,用户有什么业务逻辑,都须要写在run方法里面:

public class MyThread extends Thread{

    public void run(){

                  //做用:至关于这个线程向用户提供的接口,用户有什么样的业务逻辑,写在这个方法中

    }

}

那咱们如今就让这个run方法就实现一个简单的打印;

这个就是我使用了第一种方式来建立了一个线程;

那么,你这个线程建立完成后,若是你想调用它怎么办?

调用线程

我再建一个类(TestThread);

而后提供一个Main方法;

在main方法中建立一个线程,语法:

//建立一个线程

MyThread mt = new MyThred();

这个就是建立线程,建立完后,下一步咱们须要调用start方法;

public class TestThread{

public static void main (String [] args){

//建立线程

MyThread mt = new MyThred();

//启动线程

mt.start();

       }

   }

为何要调用start,而不是run?

其实很简单,mt.start就是启动你的线程,那么启动后,它底层就会去调用你的run方法;

这个就是线程的启动式start方法;

咱们运行一下后,看一下控制台打印:

就是一些输出,感受就跟调用方法同样,对吧;

那么,接下来,咱们看一下第二种建立方式

实现(implem) Runnable接口建立线程

这种方法跟上面的那种,大同小异,只不过上面那个是继承,这个是实现接口;

实现Runnable接口后,须要实现它的run方法;

public class MyRunnableThread implements Runable{

    public void run(){

                  //做用:至关于这个线程向用户提供的接口,用户有什么样的业务逻辑,写在这个方法中

    }

}

如今,咱们用第二种方式建立了一个线程,固然,业务逻辑跟上面的那个相同,由于举例,因此没有深究别的;

第二种方式调用线程就有所不一样

 由于运行线程永远须要Thread里面的start方法来启动线程,因此须要把Thread建立出来,再将建立出来的线程放进去;

因此打印出来的结果是跟上面的结果是同样的,这里就再也不放图上去了;

线程关键字分析

start,是线程启动的方法;

run方法是线程执行过程当中调用的方法(默认调用),在上面的例子咱们也看到了,你并无手动去调用run方法,是他自动调用的,就跟你建立对象的时候,默认调用构造方法同样;

深究run与start

那,启动线程必定是要用staet方法启动,我试试不用它,我直接调用Thread中的run方法可行吗?

可行由于抛开线程,你自己就是实例化了Thread这个类,并调用该类中的run方法是没有问题的,可是,不归入线程中!!

咱们直接调用run方法后,发现,方法能够正常打印,由于,仅仅完成了普通方法的调用,实际上并无启动线程;

相关文章
相关标签/搜索