进程
Hello.java
编译并运行Hello.java
jps查询java当前运行的进程
24900 Hello 表示名为Hello的进程正在运行
关闭运行Hello.java的cmd后再查询jps
Hello进程消失了
说明运行一个程序就会启动一个进程,进程的名字就是执行的类的名字
线程
线程可以理解成工厂的流水线,一个进程可以有多个线程
package Thread;
public class demo {
public static void main(String[] args) {
/*
Thread是线程类, Thread.currentThread()可以获取当前运行的线程
getName获取线程名称
*/
System.out.println(Thread.currentThread().getName());//main
/*main方法在一个线程中运行,这个线程的名字是main
java程序在运行时默认会产生一个进程,这个进程会有一个主线程
代码都在主线程中执行
*/
}
}
创建线程
工厂里肯定不止一条流水线,在程序中也可以如此,多几条线程来运行代码效率会提高,也可以通过不同线程来隔离逻辑
package Thread;
public class demo {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());//main
/*
Thread thread = new Thread();//创建线程
thread.start();//启动线程
光创建和启动Thread线程是没有效果的,因为没有代码可以与它关联
所以一般会自己写个线程来继承并重写Thread的方法
*/
MyThread t = new MyThread();
t.start();
System.out.println(Thread.currentThread().getName());//main
/*结果还是main,说明main方法在主线程,MyThread在新的线程,两者互不干扰
而且启动线程需要些时间,而main线程是一直都在执行的,所以t.start()的结果
比下面的getName结果要慢,控制台先打印出了main
*/
}
}
class MyThread extends Thread{//声明自定义线程类
@Override
public void run() {//重写了run方法
System.out.println("MyThread: "+Thread.currentThread().getName());//MyThread: Thread-0
}
}
线程的生命周期
线程的执行方式
当前主流CPU几乎是多核的,所以线程默认的执行方式是并发执行
即多个线程是独立的,谁抢到了CPU的执行权,谁就能先执行
package Thread;
public class demo {
public static void main(String[] args) {
MyThread0 t0 = new MyThread0();
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t0.start();
t1.start();
t2.start();
System.out.println("main线程执行完毕");
}
}
class MyThread0 extends Thread{//声明自定义线程类
@Override
public void run() {//重写了run方法
System.out.println("MyThread0: "+Thread.currentThread().getName());
}
}
class MyThread1 extends Thread{//声明自定义线程类
@Override
public void run() {//重写了run方法
System.out.println("MyThread1: "+Thread.currentThread().getName());
}
}
class MyThread2 extends Thread{//声明自定义线程类
@Override
public void run() {//重写了run方法
System.out.println("MyThread2: "+Thread.currentThread().getName());
}
}
说明线程间是独立运行的,打印顺序是不确定的。这就是并发执行
如果要是线程按顺序执行,可以将线程连接成串,称为串行执行
package Thread;
public class demo {
public static void main(String[] args) throws Exception{//join方法要产生异常
MyThread0 t0 = new MyThread0();
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t0.start();
t0.join();//将t0线程跟主线程连在一起,且t0必须在t1线程启动前执行,不然不会按顺序执行
t1.start();
t1.join();
t2.start();
t2.join();
System.out.println("main线程执行完毕");
}
}
class MyThread0 extends Thread{//声明自定义线程类
@Override
public void run() {//重写了run方法
System.out.println("MyThread0: "+Thread.currentThread().getName());
}
}
class MyThread1 extends Thread{//声明自定义线程类
@Override
public void run() {//重写了run方法
System.out.println("MyThread1: "+Thread.currentThread().getName());
}
}
class MyThread2 extends Thread{//声明自定义线程类
@Override
public void run() {//重写了run方法
System.out.println("MyThread2: "+Thread.currentThread().getName());
}
}
三个线程都串到主线程中,所以会按照顺序执行程序
线程休眠
使线程进入定时等待状态,常用于周期性工作,或者让其他线程有机会交互
package Thread;
public class demo {
public static void main(String[] args) throws Exception{
while(true){
//每3秒打印一次
Thread.sleep(3000);//在哪个线程中调用此方法,哪个线程就会休眠
//这里是主线程main
System.out.println("main线程执行完毕");
}
}
}
构建线程的多种方式
一般方法
package Thread;
public class demo {
public static void main(String[] args) {
MyThread0 t0 = new MyThread0();
t0.start();
MyThread1 t1 =new MyThread1();
t1.start();
System.out.println("main线程执行");
}
}
class MyThread0 extends Thread{
//一般构建线程的方法就是自定义线程
//1.继承线程类 2.重写run方法
@Override
public void run() {
System.out.println("t0线程执行");
}
}
class MyThread1 extends Thread{
@Override
public void run() {
System.out.println("t1线程执行");
}
}
面向对象思想方法
但这样做有个问题,每次想新增个线程就要多自定义一个线程类,这样做跟面向对象的思想有所出入
应该是定义一个线程类后就跟据这个模板来创建多个对象来实现创建多个线程
package Thread;
public class demo {
public static void main(String[] args) {
Mythread2 t2 = new Mythread2("t2");
Mythread2 t22 = new Mythread2("t22");
t2.start();
t22.start();
System.out.println("main线程执行");
}
}
class Mythread2 extends Thread{
private String threadName;
public Mythread2(String name){
this.threadName = name;
}
@Override
public void run() {
System.out.println(this.threadName+"线程执行");
}
}
传递逻辑法
如果觉得上面的代码复杂,可以用这种方法,不用自定义线程类,通过类似于箭头函数的方式传递逻辑
package Thread;
public class demo {
public static void main(String[] args) {
Thread t3 = new Thread(() -> {
System.out.println("t3线程执行");
});
t3.start();
System.out.println("main线程执行");
}
}
Runnable接口法
与上面类似,不过这个是通过Runnable接口来传递逻辑
package Thread;
public class demo {
public static void main(String[] args) {
Thread t4 = new Thread(new Runnable() {//一般用匿名类来实现接口
@Override
public void run() {
System.out.println("t4线程执行");
}
});
t4.start();
System.out.println("main线程执行");
}
}
标签:Thread,System,println,线程,进程,main,public
From: https://www.cnblogs.com/ben10044/p/17148711.html