企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
关于线程和进程的学习,我们已经进行了很多遍了,但是对于这两者的区别还是不知道怎么去理解.所以做一下总结吧。 ### 关于进程和线程的区别 **a.地址空间和其它资源**:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。 **b.通信**:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。 **c.调度和切换**:线程上下文切换比进程上下文切换要快得多。 **d.在多线程OS中,进程不是一个可执行的实体。** 一个简单的例子,就是进程就好像一个工厂,这个工厂做产品需要一些资源.而线程就好像工厂中的工人,这些工人之间的资源时共享的. ### 线程的实现 线程的实现由两种方法,一种是继承分别为继承Thread类和实现Runable接口。 下面是两段代码分别实现这两个方法。 ### 一.使用Runable接口 ~~~ public class MyThread { public static void main(String[] args) { Runner r = new Runner(); // r.run();//使用此处我们可以看到两个方法分别执行 Thread t=new Thread(r); t.start();//使用多线程,我们可以发现我们的两个方法是同时执行的 for(int i = 0;i<100;i++) { System.out.println("Main Thread:"+i); } } } class Runner implements Runnable { public void run() { for(int i=0;i<100;i++) { System.out.println("runner:"+i); } } } ~~~ ### 二.继承Thread类 ~~~ public class MyThread { public static void main(String[] args) { Runner r = new Runner(); r.start(); for(int i = 0;i<100;i++) { System.out.println("Main Thread:"+i); } } } class Runner extends Thread { public void run() { for(int i=0;i<100;i++) { System.out.println("runner:"+i); } } } ~~~   使用多线程得到的输出结果:                 ![](https://box.kancloud.cn/2016-03-23_56f1fee6c958e.jpg) 使用Runnable阶段创建线程时,需要首先编写一个实现Runnable接口的类.然后实例化该类的对象,这样就建立了  Runnable对象,接下来使用构造方法创建Thread实例.最后使用Start()方法启动线程. 当一个类继承了Thread后,就可以在该类中覆盖run()方法,将实现线程功能的代码写入run()中.然后调用Thread的Start()方法. 看过之后我们会发现两个方法是这么的相似.如果我们查API,我们就会明白实质上Thread类就是实现了Runnable接口,其中的Run方法就是对Runnable接口中Run()方法的具体实现。 ### 生命周期 线程的生命周期,包括出生、就绪、运行、等待、休眠、阻塞和死亡七种状态。 下面的一张图展示了这几个状态的联系。其中也展示了线程的一些操作 ![](https://box.kancloud.cn/2016-03-23_56f1fee6de886.jpg) ### 线程的同步 在多线程中会发生两个线程抢占资源的的问题。为了解决这个问题,java提供了线程同步机制。 我们通过一个实例来理解一下这个机制。这张图实现了一个简单的买门票的过程.门票的张数不能是负值. ~~~ public class MyThread { public static void main(String[] args) { ThreadSafeTest t = new ThreadSafeTest(); //实例化四个线程实例 Thread tA=new Thread(t); Thread tB=new Thread(t); Thread tC=new Thread(t); Thread tD=new Thread(t); //启动这四个线程实例 tA.start(); tB.start(); tC.start(); tD.start(); } } class ThreadSafeTest implements Runnable { int num=10; public void run() { while(true){ if(num>0){ try { Thread.sleep(100); } catch(Exception e) { e.printStackTrace(); } System.out.println("门票还有" + num + "张" ); num=num-1; } } } } ~~~ 执行结果为: ![](https://box.kancloud.cn/2016-03-23_56f1fee705494.jpg) 这个过程中我们可以看到出现了负值,这是由于同时创建了四个线程,这个四个线程同时执行run方法,而且这四个线程同是取得数值,同是递减.导致剩余门票的张数出现上面的情况. 然后,我们给run方法加入同步机制. ~~~ public class MyThread { public static void main(String[] args) { ThreadSafeTest t = new ThreadSafeTest(); //实例化四个线程实例 Thread tA=new Thread(t); Thread tB=new Thread(t); Thread tC=new Thread(t); Thread tD=new Thread(t); //启动这四个线程实例 tA.start(); tB.start(); tC.start(); tD.start(); } } class ThreadSafeTest implements Runnable { int num=10; public void run() { while(true) { synchronized("")//该关键字的使用就保证了同步 { if(num>0){ try { Thread.sleep(100); } catch(Exception e) { e.printStackTrace(); } System.out.println("门票还有" + num + "张" ); num=num-1; } } } } } ~~~ ![](https://box.kancloud.cn/2016-03-23_56f1fee713e45.jpg) ### 总结 学习了多线程编程就像进入了一个全新的领域,它与以往的编程思想不同,现在很多的程序语言都以支持和扩展多线程,作为初学者应该及时转变我们的编程思路,是我们的变成进入一个多线程编程的思维方式.同时多线程也是一种复杂的机制,完全理解它我们还要更深入的去研究