当前位置: 移动技术网 > IT编程>开发语言>Java > 荐 java学习(六)多线程 上

荐 java学习(六)多线程 上

2020年07月12日  | 移动技术网IT编程  | 我要评论

进程:进程是一个正在执行的程序,这个程序呢都有一个执行顺序,这个执行顺序是一个执行路径,或者说是一个控制单元。在这里插入图片描述
所有的进程不会同时发生,而是来回切换。

线程:打个比方,一堆货物,一个人搬花十个小时,十个人搬花费一个小时。线程在进程中的作用就类似这个,线程在控制着进程执行,一个进程起码有一个线程,线程可以同时发生。

那咱们怎么在程序中用多线程。

package tread;

class Demo extends Thread
{
	public void run() {
		System.out.print("线程开始启动");
		for(int a=0;a<50;a++)
			System.out.println("run"+a);
		
	}
}
public class acsad
{
	public static void main(String[] args) {
		Demo d = new Demo();
		d.start();
		/*
		 * 创建并使用线程
		 * start()方法会启动线程,并调用run方法
		 */
		for(int a=0;a<50;a++)
			System.out.println("main"+a);
	}
}
部分输出:
main0
main1
线程开始启动main2
run0
main3
main4
main5
main6
main7
main8
main9
main10
main11
main12
main13
main14
main15
run1
main16
main17
run2
main18
main19
main20
main21
run3
run4
run5
run6
run7
run8
run9
run10
run11
run12

大家可以看到,run和main是交叉运行,开始的时候程序运行,系统自动开一个主线程运行主函数,运行到建立线程那里,又开了一条d线程,这两个线程谁抢到了cup使用权,谁就输出,所以交叉进行。在 某一个时刻只能有一个程序正在运行。(多核除外)

现在教一个概念:(处理器是CPU)

多个处理器:多个单核处理器,就是说电脑和处理器有多个,但是这个电脑的处理器是单核的;

多核处理器:单个多核处理器,也就是说电脑有一个处理器,但是这个处理器是多核的;

    当然他们之间有这个很大的区别,对于这两个疑点,或许你一直是这么认为的(对于时间的执行效率有区别),但是更重要的不止这些,最为重要的是它们的资源利用率问题,下面我们讨论一下关于二者究竟谁更优秀:

    对于多个处理器而言,它们在执行命令的时候多个处理器之间的通信手段是电脑主板上的总线;而对于多核处理器而言,多个核心处理器之间通信时通过CPU内部总线进行信息的交互的。对于执行效率而言,多核处理器要优于多个处理器,在生活中,我们的电脑上常见的处理器都是单处理器,但是这个处理器是多核的,当然,一些IT工作者的电脑如果是在要求较高的环境下工作时,都采用的多个多核处理器配置。

   当然对于进程和线程问题而言,结合处理器问题,是这样的,进程资源调度的基本单位,线程是进程的一个实体,是一个执行单元,一个进程可能包含有很多个线程,计算机在启动之后,一个进程最少包含一个主线程,如果这个主线程结束了,那么这个进程也就终止执行了,主线程是以函数的形式提供给操作系统的。对于并行计算是在多处理器的情况下,操作系统把多个线程分配给响应的处理器,然后各自执行任务。

———————————————— 版权声明:本文为CSDN博主「Kevin_YZLong」的原创文章,遵循CC 4.0
BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Kevin_YZLong/article/details/70196168

这里注意一下run()方法在继承线程类之后需要重写,run()方法就是线程要运行的代码。

以上就是创建线程的第一种方法:

1.继承Tread类
2.重写run()方法
3.创建子类对象
4.用start()方法开启线程并启动run()方法

咱们进行线程切换的时候,之前运行的线程怎么停止?
1.用sleep()函数停止到一定时间重启
2.用wait()函数去等待,可以用notify()去唤醒wait()的等待。线程运行
3.用stop()函数让线程消亡(程序结束)

那么线程怎么分辨,一号线程,二号线程等等会不会乱?
不会的,线程都有自己的名称,通过getName()函数获得,而且线程在初始化的时候可以用带参构造函数,没有就用默认的。
气死我了,上代码:

package tread;

class Demo extends Thread
{
	Demo(String name){
		super(name);
	}
	public void run() {
		System.out.print(this.getName()+"开始启动");
		
	}
}
public class acsad
{
	public static void main(String[] args) {
		Demo d = new Demo("一号线程");
		d.start();
		/*
		 * 创建并使用线程
		 * start()方法会启动线程,并调用run方法
		 */
	}
}
输出:一号线程开始启动
我们也可以用setName()去设置线程名称

那我们可以获得当前运行的线程对象的名称吗?用currentThread()函数可以解决,

package tread;

class Demo extends Thread
{
	Demo(String name){
		super(name);
	}
	public void run() {
		if(Thread.currentThread() == this) {
		System.out.print(this.getName() + "开始启动");
		}
	}
}
public class acsad
{
	public static void main(String[] args) {
		Demo d = new Demo("一号线程");
		d.start();
		/*
		 * 创建并使用线程
		 * start()方法会启动线程,并调用run方法
		 */
	}
}
输出:一号线程开始启动

例子:老师要求学生们写作业,小明小红小张同时做作业,这个作业一共一百道题。用多线程来显示做题过程:

package tread;

class Test extends Thread
{   Test(String name){
	super(name);
}
    private int t=0;
	public void run() {
		
		while(true) {
			if(t<=100) {
				System.out.println("这是"+this.getName()+"完成的第" + ++t + "道题");
			}
		}
	}
}
public class acsad
{
	public static void main(String[] args) {
		Test 小明 = new Test("小明");
		Test 小红 = new Test("小红");
		Test 小张 = new Test("小张");
		小明.start();
		小红.start();
		小张.start();
	}
}
部分输出为:
这是小张完成的第1道题
这是小张完成的第2道题
这是小张完成的第3道题
这是小张完成的第4道题
这是小红完成的第1道题
这是小红完成的第2道题
这是小红完成的第3道题
这是小红完成的第4道题
这是小明完成的第1道题
这是小红完成的第5道题
这是小红完成的第6道题
这是小红完成的第7道题
这是小张完成的第5道题
这是小红完成的第8道题
这是小明完成的第2道题
这是小红完成的第9道题
这是小张完成的第6道题
这是小张完成的第7道题
这是小红完成的第10道题
这是小明完成的第3道题
这是小红完成的第11道题
这是小张完成的第8道题
这是小红完成的第12道题
这是小明完成的第4道题
这是小红完成的第13道题
这是小张完成的第9道题

现在写第二种建立多线程的方法,咱们直接上代码:

package tread;

class Test implements Runnable
{   public void run() {
	System.out.print("print线程");
}
  
}
public  class acsad
{
	public static void main(String[] args) {
     Test t=new Test();
     Thread t1=new Thread(t);
     t1.start();

	}

}
输出:print线程

第二种方法步骤:

1.定义Runnable接口
2.通过Thread类建立线程对象
3.将Runnable接口的子类对象作为实际参数传递给Thread的构造函数
4.调用start()函数执行在Runnable里写的run()函数

上代码:

package tread;

class Test implements Runnable
{   public void run() {
	System.out.print("print线程");
}
}
public  class acsad
{
	public static void main(String[] args) {
     Test t=new Test();
     Thread t1=new Thread(t);
     t1.start();
	}
}
输出:print线程

这里就算写个类继承Runnable接口,然后再把接口传输给一个线程,可以直接用。

本文地址:https://blog.csdn.net/weixin_45743162/article/details/107243635

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网