java多线程基础学习
一 进程和线程
线程:线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
进程:进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。
进程和线程的区别:线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。
二 多线程
一个进程中也可以同时并发处理多个任务,在同一程序中有多个顺序流在执行,在java中想要实现多线程有两种手段,一种是继承Thread类,另一种是实现Runnable接口
三 使用多线程
1.继承Thread类
public class MyThread extends Thread{ public void run(){ super.run(); System.out.println("MyThread"); } } public void thread1() throws InterruptedException { MyThread myThread = new MyThread(); myThread.start(); System.out.println("运行结束了!!!!!!!!"); }
从源码中可以发现Thread类实现了Runnable接口,他们之间具有多态关系
public class Thread implements Runnable
注:使用继承Thread类的方式创建新线程时,不支持多继承,因为java语言的特点是单根继承
2.实现Runnable接口
public class Runnables implements Runnable { @Override public void run() { System.out.println("正在运行中!"); } } public void thread1() throws InterruptedException { Runnables runnables =new Runnables(); Thread thread =new Thread(runnables); thread.start(); System.out.println("运行结束了!!!!!!!!"); }
实现Runnable接口比继承Thread类所具有的优势:可以避免java中的单继承限制,增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
其实main方法也是一个线程,所有线程都是同时启动的,但是是谁先夺得cpu资源谁先执行。
java中每次程序运行都会运行main线程和垃圾收集线程。
四 线程间的状态转换图
线程状态转换图
- 新建状态(New):新创建了一个线程对象。
- 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
- 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
- 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5.死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
五 线程中的方法
1.currentThread()方法:可以返回代码正在被那个线程调用的信息
2.isAlive()方法:判断当前线程是否处于活动状态
public class MyThread extends Thread{ private int coun =5; public void run(){ super.run(); System.out.println("run =" + this.isAlive()); } } pu
public class MyThread extends Thread{ private int coun =5; public void run(){ super.run(); System.out.println("run =" + this.isAlive()); } } public void thread1() throws InterruptedException { MyThread myThread = new MyThread(); System.out.println("begin ="+ myThread.isAlive() ); myThread.start(); Thread.sleep(1000); System.out.println( "end = "+ myThread.isAlive() ); } 输出结果为: begin =false run =true end = false
上面两段代码可以看出在睡眠1000毫秒的之后,已经执行完毕了,所以状态时false
blic void thread1() throws InterruptedException { MyThread myThread = new MyThread(); System.out.println("begin ="+ myThread.isAlive() ); myThread.start(); System.out.println( "end = "+ myThread.isAlive() ); } 打印结果为: begin =false end = true run =true
3.sleep()方法:在指定时间内让当前正在执行的线程进入休眠状态
4.getId()方法:取得现成的唯一标识
六 停止线程
停止线程是多线程开发是很重要的技术点,掌握此技术可以对线程的停止进行有效地处理
在java中有三种方法可以终止正在运行的线程
1)使用推出标志,使线程正常退出,也就是run方法结束之后程序停止
2)使用stop方法强行终止,但是不推荐使用这个方法(已过期)
3)使用interrupt方法中断线程
判断线程是否停止
this,interrupt()方法:测试当前线程是否已经是中断状态,执行后具有将状态标志置清除为flse的功
this.isInterrupted()方法:测试线程Thread对象是否已经是中断状态,但不清楚状态标志