java-day42
文章目录
线程
线程的概念
创建、初始化、启动一个新的线程
线程状态的转换
并发访问,线程同步
线程通信
线程的作用:
我们所编写的代码最终都是要加载到内容,然后被JVM中的线程去一行行的执行。
线程的分类:
前台线程(执行线程):
main线程–>任务目标:执行用户的代码(main方法开始执行)
当前JVM中所有的前台线程执行完毕,那么JVM就自动停止了,因为这个时候说明用户的代码已经全部执行结束了。
如果是单线程,那么前台只有一个:main线程
如果是多线程,那么前台线程就会出现多个: main线程 t1 t2 t3 t4 …
后台线程(守护线程):
执行JVM已有的代码,给前台线程提供服务,打造良好的运行环境。
例如:执行垃圾回收的代码,就是由一个后台线程负责的,当前前台线程创建对象并使用后,这个gc线程就可以找合适的时间点,把这个不再使用的对象给回收了,这样以来,我们的前台线程下次又可以使用这块内存空间了。
JVM停止运行有一个重要的标志:
当前JVM中所有的前台线程执行完毕,都处于死亡状态,那么JVM就停止运行。
JVM的停止是不关心后台线程的运行情况和状态的。
进程中的线程
进程只能拿到计算机中的资源,并不能执行代码。而进程中创建出来的线程,就可以执
行代码。
再线程执行代码的过程中,如果需要用计算机的资源,那么这个线程可以直接在它所属
的进程中获取。
线程不能单独存在,线程只能依附在某一个进程中,才能运行。
线程的组成部分
code cpu data
一个线程在工作的时候,主要是围绕这三个方法开展的。线程中加载了要执行的代码, 线程中还有要代码中要操作的数据,在根据代码来操作数据的时候,需要使用cpu进行数据的计算。
注意,这些操作的过程都是在内存中进行的。
创建线程的两种方式
1、继承Thread类
在一个线程t1中可以创建并启动一个新的线程对象t2,但是t2线程被启动后就可以自己独立运行了,这个时候t1和t2之间互不影响。
public static void main(String[] args) throws InterruptedException {
String name = Thread.currentThread().getName();
System.out.println(name+"线程执行开始");
ThreadTest2 t = new ThreadTest2();
t.test1();
System.out.println(name+"线程执行结束");
}
//使用继承的方式,创建线程
public void test1() {
Thread t1 = new Thread("t1") {
@Override
public void run() {
//当前方法的线程名字
String name = Thread.currentThread().getName();
for(int i=0;i<1;) {
System.out.println(name+"hello");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
//启动线程,线程启动会自动调用run方法
t1.start();
}
在上面这个例子,main线程启动并开启t1线程
线程只要不启动和普通变量没有区别。
//t1.start();
t1.run();
修改上面的操作,t1线程未启动,还在main线程中
2、实现Runnable接口的方式
public static void main(String[] args) throws InterruptedException {
String name = Thread.currentThread().getName();
System.out.println(name+"线程执行开始");
ThreadTest2 t = new ThreadTest2();
t.test2();
System.out.println(name+"线程执行结束");
}
//使用接口的方式创建
public void test2() {
//注意,这个run对象不是线程,run对象中有我们设置好的任务
//这个任务需要交给一个线程对象去执行
Runnable target = new Runnable() {
//run方法中就是线程对象需要独立运行的代码
@Override
public void run() {
String name = Thread.currentThread().getName();
for(int i=0;i<1;) {
System.out.println(name+" world");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
//t2是线程对象
Thread t2 = new Thread(target,"t2");
//启动t2线程
t2.start();
}
进程
进程就是计算机中一组资源的集合,包括计算机的软件资源和硬件资源,包括CPU/内存/磁盘/网络/计算机设备(鼠标、键盘、屏幕等)
只要在计算机中启动了一个软件或运行了一个程序,那么这时候至少会有一个进程和这个软件或程序相对应,每个进程都是有编号的(PID),通过强行杀死这个进程,就可以关闭对应的软件或程序。例如可以在Linux中使用kill杀死进程,kill -9 pid。
计算机中的每个软件的启动运行,都会对应至少一个进程。
线程不能单独存在,线程需要依附在进程中,因为进程中有从计算机系统中申请获取资源(CPU/内存/磁盘/网络…),但是线程中并没有这些资源,线程只能执行代码,但是需要执行代码的时候,需要用到计算机中的各种资源.
当使用java命令运行一个java类的时候,首先会启动一个JVM,那这个JVM在计算机中,就是一个进程,我们是可以找到这个JVM的PID的。
例如:java com. zzb.day42.Hello
如果使用java命令连续运行俩次java类,那么会产生俩个JVM的进程。
例如:java com. zzb.day42.Hello
java com. zzb.day42.Hello
假如Hello这个类需要运行10分钟,那么由于运行了俩次,在这10分钟中,电脑里面有会有俩个JVM的进程
JDK自带工具jconsole命令,可以连接到当前电脑中所有的JVM进程中,观察进程中资源的使用情况,在连接列表中,会列出当前电脑里面有哪些JVM的进程,会显示这些进程的PID,以及这些进程是由于运行哪个java类而产生的。