线程的使用

本文详细介绍了Java中的多线程概念,包括程序、进程和线程的区别,以及线程的创建和运行机制。通过实例展示了如何通过继承Thread类和实现Runnable接口创建线程,还探讨了线程的join、优先级、sleep和yield方法,揭示了线程调度的策略。
摘要由CSDN通过智能技术生成
package cn.ekgc.javasenior.day20210630;

public class ThreadNote {
	public static void main(String[] args) {
		/*
		 * 1、程序、进程和线程:
		 * (1)程序:由代码组成,为了完成某项功能业务,或者是实现某个应用而形成的代码集合。
		 * 程序本身就是一个静止的概念,也就是当通过代码写完之后,就能够得到一个程序。
		 * (2)进程:当开始通过 CPU 去执行某个程序的代码时,那么这个程序就需要操作系统开始独立分配存储空间,
		 * 将其的代码交给 CPU 开始运行,那么这个时候,这个静止的程序,就成为了动态的进程。
		 * 程序是静止的,而进程就是运行的程序,是一个动态的。
		 * 对于进程来说,有如下的特征:
		 * A、是动态运行的;
		 * B、是计算机运行的独立单位;
		 * C、操作系统在分配内存空间时,是以进程为单位进行分配的,每个进程之间的存储空间是独立的,相互不干扰。
		 * 进程的缺点在于,一个独立的进程会执行很多的代码,往往所需要的时间或者是等待时间过长,
		 * 例如微信在聊天时,就会有大量空闲的时间在等待用户的输入,而 CPU 的执行效率较高,
		 * 就会造成 CPU 在大量时间下一直处于空转状态。造成 CPU 的资源浪费。
		 * 如果 CPU 的运行是以进程为单位执行的话,那么就会造成 CPU 在大部分时间下处于空转,
		 * 而且还不允许其他进程执行,造成宝贵的 CPU 资源浪费。
		 * (3)线程:线程是 CPU 运行的最小单位,是将一个独立的进程再次进行细化,变为多个更小的运行单位,
		 * 我们将这个单位就称之为线程。由于线程是 CPU 运行的最小单位,因此对于 CPU 来说,是不存在进程这一概念,
		 * 那么他就可以在多个线程之间进行轮流交替执行,提高 CPU 的工作效率。
		 * 线程存在的最重要的目的就是减少 CPU 的空转时间,提高 CPU 的利用率。
		 * 2、多线程指的就是一个程序在执行的时候,可以同时存在多个线程。自此之前,我们所写的所有程序,
		 * 本质上只有一个线程,那么就是由 main() 方法所创建的线程,我们称之为主线程。
		 * 每开辟一个线程,那么这个线程就脱离了主线程,能够独立运行。
		 * 3、线程的特征:
		 * (1)线程是 CPU 执行的最小单位;
		 * (2)一个进程内可以存在多个线程;
		 * (3)一个进程内的多个线程之间是共享内存的,相互之间是可以通讯交流的。
		 * 4、对于 Java 来说,要想实现多线程,是很简单的,因为 Java 已经将多线程的实现进行了封装,
		 * 我们只需要直接使用即可。
		 */
	}
}

 Thread

package cn.ekgc.javasenior.day20210630.base;

public class ThreadDemo01 {
	public static void main(String[] args) {
		// 创建 MyThread 对象
		MyThread myThread = new MyThread();
		// 对于每个线程,都可以进行命名,则通过该线程的 setName() 进行命名
		myThread.setName("李静平");
		// 如果只是创建了一个线程对象,那么这个线程是不执行的,需要调用该线程对象的 start() 启动该线程
		// 即使启动了一个线程,那么这个线程也不一定就立刻被执行,只有当操作系统调度该线程为其分配 CPU 资源后,
		// 这个线程才能够执行。
		myThread.start();
		// 那么此时对于操作系统来说就存在两个线程,分别是 main 和 myThread,
		// 当 myThread 启动后,这个线程就脱离了 main 的管理,独立运行,
		// 也设定 main 线程运行的内容
		for (int i = 0; i < 100; i++) {
			System.out.println("这是 main 线程的第 " + (i + 1) + " 次输出!");
		}
	}
}

// 一个 .java 文件中,可以存在多个 class 类,但是只能够有一个 public class
// 虽然多个 class 可以写在一个 .java 文件中,但是编译之后获得的 .class 文件
// 确是一个 class 类一个独立的 .class 文件。
// 要想获得一个能够创建线程的类,只需要让该类继承 java.lang.Thread 类即可
class MyThread extends Thread {
	// 对于一个线程来说,只运行该线程的 run(),因此需要运行的代码必须写在 run()
	// 重写 run()
	@Override
	public void run() {
		// 如果需要得到到时候的线程名,则可以通过 Thread.currentThread().getName() 获得
		String threadName = Thread.currentThread().getName();
		// 当创建了一个 MyThread 线程执行,会执行的代码
		for (int i = 0; i < 100; i++) {
			System.out.println("这是 " + threadName + " 线程的第 " + (i + 1) + " 次输出!");
		}
	}
}
package cn.ekgc.javasenior.day20210630.base;

public class Threadtest {
public static void main(String[] args) {
	Mythread01 my = new Mythread01();
	my.setName("李静平");
	my.start();
	for(int i = 0;i<10;i++) {
		System.out.println("这是main第"+(i+1)+"次运行");
		
		}
	}
}
class Mythread01 extends Thread{
	
	@Override
	public void run() {
		String threadname = Thread.currentThread().getName();
		for(int i = 0;i<10;i++) {
			System.out.println("这是"+threadname+"第"+(i+1)+"次运行");
			
		}
	}
	
}

 Runnable

package cn.ekgc.javasenior.day20210630.base;

public class RunnableDemo01 {
	public static void main(String[] args) {
		// 创建 MyRunnable 类的对象
		MyRunnable myRunnable = new MyRunnable();
		// 创建 Thread 对象,并且将 MyRunnable 对象作为构造方法的参数传入
		Thread myThread = new Thread(myRunnable);
		// 启动 myThread 线程
		myThread.start();
		
		for (int i = 0; i < 100; i++) {
			System.out.println("这是 main 的第 " + (i + 1) + " 次运行!");
		}
	}
}

// 要想获得一个多线程类,除了继承 Thread 类,也可以实现 Runnable 接口
class MyRunnable implements Runnable {
	// 对于实现了 Runnable 接口的类对象,只是线程在启动后需要运行的部分,
	// 而不是线程本身
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("这是 MyRunnable 的第 " + (i + 1) + " 次运行!");
		}
	}
}
package cn.ekgc.javasenior.day20210630.base;

public class Runnabletest {
	public static void main(String[] args) {
		Thread my01 = new Thread(new MyRunnable01());
		my01.start();
		for(int i = 0;i<10;i++) {
			System.out.println("这是main第"+(i+1)+"次运行");
			}
			}
		}

class MyRunnable01 implements Runnable{

	@Override
	public void run() {
		for(int i = 0;i<10;i++) {
			System.out.println("这是Runnable第"+(i+1)+"次运行");
			}
	}
}
package cn.ekgc.javasenior.day20210630.schedule;

public class JoinDemo {
	public static void main(String[] args) {
		// 创建 MyJoinThread 对象
		MyJoinThread joinThread = new MyJoinThread();
		// 设定当前线程名
		joinThread.setName("MyJoinThread");
		
		for (int i = 0; i < 10; i++) {
			System.out.println("这是 main 线程的第 " + (i + 1) + " 次运行!");
			if (i == 5) {
				// 启动线程
				// 启动 MyJoinThread 线程
				joinThread.start();
				// 该线程启动后,直接加入运行,让 main 进入到等待阻塞中
				try {
					joinThread.join();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

class MyJoinThread extends Thread {
	@Override
	public void run() {
		// 获得当前线程名
		String name = Thread.currentThread().getName();
		for (int i = 0; i < 10; i++) {
			System.out.println("这是 " + name + " 的第 " + (i + 1) + " 次运行!");
		}
	}
}
package cn.ekgc.javasenior.day20210630.schedule;

public class PriorityDemo {
	public static void main(String[] args) {
		// 创建 MyThread 对象
		MyPriorityThread myThread = new MyPriorityThread();
		// 对 myThread 线程进行命名
		myThread.setName("MyThread");
		/*
		 * 对于任意的一个线程,都存在优先级别,分别是从 1 ~ 10,默认为 5。
		 * 也就是每个线程都有平等的抢占 CPU 资源的能力。
		 * 但是如果需要某些线程更好的能够抢占到 CPU 资源,
		 * 那么可以通过调整该线程的优先级别,来调整该线程抢占 CPU 的能力,
		 * 表明该线程抢占 CPU 能力越高,抢占到 CPU 的概率越大。
		 * 但是不保证就一定能够抢到 CPU 资源。
		 */
		// 在该线程启动前,可以调整线程的优先级别
		myThread.setPriority(10);
		// 启动 myThread 线程
		myThread.start();
		
		for (int i = 0; i < 10; i++) {
			System.out.println("这是 main 的第 " + (i + 1) + " 次运行!");
		}
	}
}

class MyPriorityThread extends Thread {
	@Override
	public void run() {
		// 获得当前线程的线程名
		String name = Thread.currentThread().getName();
		
		for (int i = 0; i < 10; i++) {
			System.out.println("这是 " + name + " 的第 " + (i + 1) + " 次运行!");
		}
	}
}
package cn.ekgc.javasenior.day20210630.schedule;

public class SleepDemo {
	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			System.out.println("这是 main 的第 " + (i + 1) + " 次运行!");
			// 让 main 线程,每一轮循环都休眠 1s
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
package cn.ekgc.javasenior.day20210630.schedule;

public class SortDemo {
	public static void main(String[] args) {
		int[] nums = {10, 2, 9, 1, 6, 5, 7};
		for (int i = 0; i < nums.length; i++) {
			SortThread sortThread = new SortThread(nums[i]);
			sortThread.start();
		}
	}
}

class SortThread extends Thread {
	private int num;
	
	public SortThread(int num) {
		this.num = num;
	}
	
	@Override
	public void run() {
		// 根据 num,让当前线程进行休眠
		try {
			Thread.sleep(num * 1000);
			System.out.println(num);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
package cn.ekgc.javasenior.day20210630.schedule;

public class YieldDemo {
	public static void main(String[] args) {
		// 创建 MyJoinThread 对象
		YieldThread yieldThread = new YieldThread();
		// 设定当前线程名
		yieldThread.setName("YieldThread");
		yieldThread.start();
		
		for (int i = 0; i < 10; i++) {
			System.out.println("这是 main 线程的第 " + (i + 1) + " 次运行!");
			// 每次输出完,都将 main 移出 CPU
			Thread.yield();
		}
	}
}

class YieldThread extends Thread {
	@Override
	public void run() {
		// 获得当前线程名
		String name = Thread.currentThread().getName();
		for (int i = 0; i < 10; i++) {
			System.out.println("这是 " + name + " 的第 " + (i + 1) + " 次运行!");
		}
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值