J2SE的学习——Java多线程

对多线程的理解

定义:同时对多项任务加以控制
什么是对线程呢?可以理解成一边吃饭,一边听音乐,如果是先吃饭再听音乐或者先听音乐再吃饭,那这就是单线程的,在这里可以把线程理解成一段程序或者一件事。

意义:java多线程的存在,能让我们同事控制多个任务的执行,同事干多件事,能够充分的利用CPU、内存等硬件设备,现代的计算机都是围绕着存储器操作的,所以CPU(中央处理器)的资源运用并不是很充分,多线程的带入,能够使我们高效的使用计算机的资源,操作系统中的进程是管理着多个线程的。

Java多线程的引入

创建一个测试用的Test01
代码如下:

package Java多线程;

public class Test01 {
	//做听音乐这个操作
	private static void music(){
		for(int i=0;i<10;i++){
			System.out.println("听音乐");
		}
	}
	//做吃饭这个操作
	private static void eat(){
		for(int i=0;i<10;i++){
			System.out.println("吃饭");
		}
	}
	public static void main(String[] args) {
		music();
		eat();
	}
}

效果图:
在这里插入图片描述
得到的效果是先听音乐再吃饭

现在开始引入多线程的概念
创建两个继承线程的类,这两个类分别是Music类和Eat类,创建一个用于测试的Test02类
Music类

package Java多线程;

public class Music extends Thread{

	@Override
	public void run() {
		for(int i=0;i<10;i++){
			System.out.println("听音乐");
		}
	}

}

Eat类

package Java多线程;

public class Eat extends Thread{

	@Override
	public void run() {//重写run方法
		for(int i=0;i<10;i++){
			System.out.println("吃饭");
		}
	}

}

测试类

package Java多线程;

public class Test02 {
	public static void main(String[] args) {
		Music musicThread=new Music();
		Eat EatThread=new Eat();
		musicThread.start();
		EatThread.start();
	}
	
}

效果图
在这里插入图片描述
由于电脑的运行的速度太快了,所以看到的效果很奇怪,写一个休眠的效果,控制代码执行的效果
修改后的Music类

package Java多线程;

public class Music extends Thread{

	@Override
	public void run() {
		for(int i=0;i<10;i++){
			try {
				Thread.sleep(1000);
				System.out.println("听音乐");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

}

修改后的Eat类

package Java多线程;

public class Eat extends Thread{

	@Override
	public void run() {//重写run方法
		for(int i=0;i<10;i++){
			try {
				Thread.sleep(1000);//1秒执行一次
				System.out.println("吃饭");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

}

测试类不变
效果如下
在这里插入图片描述

Java多线程的实现

1.继承Thread类
代码

package Java多线程的实现;

public class Thread01 extends Thread{
	private String threadName;//给线程取名

	public Thread01(String threadName) {
		super();
		this.threadName = threadName;
	}

	@Override//这里的run是线程具体要做的事
	public void run() {
		for(int i=1;i<10;i++){
			System.out.println(threadName+"今天吃的第"+i+"碗饭");
		}
	}
	
	public static void main(String[] args) {
		Thread01 t1=new Thread01("张三线程");
		Thread01 t2=new Thread01("李四线程");
		t1.start();//启动线程
		t2.start();//启动线程
	}
}

看一下效果
在这里插入图片描述可以看到他们是一起吃饭的,不过后面明显李四吃的越来越快的。

3.多线程实现数据共享
实现Runnable接口
Thread02的代码如下

package Java多线程的实现;

public class Thread02 extends Thread implements Runnable{
	private int rice=1;
	private String threadName;//给线程取名

	public Thread02(String threadName) {
		super();
		this.threadName = threadName;
	}

	@Override//这里的run是线程具体要做的事
	public void run() {
		while(rice<=10){
			System.out.println(threadName+"今天吃的第"+rice+"碗饭");
			rice++;
		}
	}
	public static void main(String[] args) {
		Thread02 t1=new Thread02("张三线程");
		Thread02 t2=new Thread02("李四线程");
		Thread t11=new Thread(t1);//把线程传进去
		Thread t12=new Thread(t2);
		t11.start();
		t12.start();
	}
}

效果图
在这里插入图片描述
主要的区别是,这样的实现方法可以实现数据的共享,下面岁对Thread02的改进
Thread03的代码如下

package Java多线程的实现;

public class Thread03 extends Thread implements Runnable{
	private int rice=1;
	private String threadName;//给线程取名

	public Thread03(String threadName) {
		super();
		this.threadName = threadName;
	}

	@Override//这里的run是线程具体要做的事
	public void run() {
		while(rice<=10){
			System.out.println(threadName+"今天吃的第"+rice+"碗饭");
			rice++;
		}
	}
	public static void main(String[] args) {
		Thread03 t1=new Thread03("超级张三线程");
		Thread t11=new Thread(t1);//把线程传进去
		Thread t12=new Thread(t1);
		Thread t13=new Thread(t1);
		//上面的这三个线程有可能是同时进入这个run方法的,所以会出现三个人吃一碗饭的感觉
		t11.start();
		t12.start();
		t13.start();
	}
}

在这里插入图片描述上面就实现了三个人做同一件事,这里的超级张三代表的就是张三一号,张三二号,张三三号。
解决多个线程一起使用Run方法,看下面的效果,直接给run方法加上一个锁,让这个方法不能同时被多个线程使用!
在这里插入图片描述这个锁的作用就像门一样,上厕所门关上门就不会出现多个人挤进一个厕所的尴尬情况了。

线程的状态

在这里插入图片描述图片来源于网络,随便搜索的一个操作系统的进程的状态图,学过操作系统的都知道,这个图是要会默写的.
所有状态:

1,创建状态
在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此时,它已经有了相应的内存空间和其他资源,但还处于不可运行状态。新建一个线程对象可采用Thread 类的构造方法来实现,例如,“Thread thread=new Thread();”。

2,就绪状态

新建线程对象后,调用该线程的start()方法就可以启动线程。当线程启动时,线程进入就绪状态。此时,线程将进入线程队列排队,等待CPU 服务,这表明它已经具备了运行条件。

3,运行状态

当就绪状态的线程被调用并获得处理器资源时,线程就进入了运行状态。此时,自动调用该线程对象的run()方法。run()方法定义了该线程的操作和功能。

4,堵塞状态

一个正在执行的线程在某些特殊情况下,如被人为挂起或需要执行耗时的输入/输出操作时,将让出CPU 并暂时中止自己的执行,进入堵塞状态。堵塞时,线程不能进入排队队列,只有当引起堵塞的原因被
消除后,线程才可以转入就绪状态。

5,死亡状态
线程调用stop()方法时或run()方法执行结束后,即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
以上解释来源于小峰大佬写的,最近一直在学习他的视频,直接引入过来了,好东西大家一起分享。
怎么说呢,这个解释更趋近于开发的时候的思维的理解,和操作系统的底层的运行的解释方法不太一样,不过,本质和效果以及带来的影响基本是一样的。(本人理解是这样的,建议自己去理解,其实我也很水的。)

currentThread()方法

作用:返回该线程的名称

getName()方法

作用:返回对当前正在执行的线程对象的引用

两种方法简单的实现如下,看一下线程的状态。

package Java多线程的状态;

public class Demo01 implements Runnable{
	
	
	@Override
	public void run() {
		for(int i=0;i<10;i++){
			Thread thread=Thread.currentThread();//返回的是一个对象
			System.out.println(thread.getName()+":"+i);
		}
	}
	public static void main(String[] args) {
		Demo01 demo01=new Demo01();
		new Thread(demo01).start();//把线程传进去,默认的是第0个线程
		new Thread(demo01).start();//默认的是第一个线程
	}

}

效果
在这里插入图片描述我们通过getName获得的线程的名字是默认的,自动取的,所以能看到我们创建的两个线程,一个默认的是0,一个默认的是1。
进入了这个方法可以看到,我们是可以自己取名字的
在这里插入图片描述
看取了名字的线程

package Java多线程的状态;

public class Demo01 implements Runnable{
	
	
	@Override
	public void run() {
		for(int i=0;i<10;i++){
			Thread thread=Thread.currentThread();//返回的是一个对象
			System.out.println(thread.getName()+":"+i);
		}
	}
	public static void main(String[] args) {
		Demo01 demo01=new Demo01();
		new Thread(demo01).start();//把线程传进去,默认的是第0个线程
		new Thread(demo01).start();//默认的是第一个线程
		new Thread(demo01,"我是一个点的线程").start();//默认的是第一个线程
	}

}

效果图
在这里插入图片描述

isAlive()方法

作用:测试线程是否处于活跃状态

sleep()方法

作用:线程休眠

测试用的代码:

package Java多线程的状态;

public class Demo2 implements Runnable{
	
	
	@Override
	public void run() {
		for(int i=0;i<10;i++){
			Thread thread=Thread.currentThread();//返回的是一个对象
			System.out.println(thread.getName()+":"+i);
		}
	}
	public static void main(String[] args) {
		Demo2 demo02=new Demo2();
		Thread t1=new Thread(demo02);
		System.out.println("线程t1的状态是否开:"+t1.isAlive());
		t1.start();
		System.out.println("线程t1的状态是否开:"+t1.isAlive());
	}

}

效果
在这里插入图片描述

setPriority(int newPriority)方法

作用:更改线程的优先级

代码实现

package Java多线程的状态;

public class Demo3 implements Runnable{
	
	
	@Override
	public void run() {
		for(int i=0;i<10;i++){
			try {
				Thread.sleep(100);
				Thread thread=Thread.currentThread();//返回的是一个对象
				System.out.println(thread.getName()+":"+i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}
	public static void main(String[] args) {
		Demo3 demo03=new Demo3();
		Thread t1=new Thread(demo03,"线程A");
		Thread t2=new Thread(demo03,"线程B");
		Thread t3=new Thread(demo03,"线程C");
		t1.setPriority(Thread.MAX_PRIORITY);//优先级最高
		t2.setPriority(Thread.MIN_PRIORITY);//优先级最低
		t3.setPriority(Thread.NORM_PRIORITY);//普通优先级
		t1.start();
		t2.start();
		t3.start();
	}

}

效果
在这里插入图片描述

yield()方法

作用:暂停现在执行的线程的对象,让其他线程的对象先执行

package Java多线程的状态;

public class Demo4 implements Runnable{
	
	
	@SuppressWarnings("static-access")
	@Override
	public void run() {
		for(int i=0;i<10;i++){
			try {
				Thread.sleep(100);
				Thread thread=Thread.currentThread();//返回的是一个对象
				System.out.println(thread.getName()+":"+i);
				if(i==5){
					System.out.println("线性礼让:");
					thread.yield();
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}
	public static void main(String[] args) {
		Demo4 demo03=new Demo4();
		Thread t1=new Thread(demo03,"线程A");
		Thread t2=new Thread(demo03,"线程B");
		Thread t3=new Thread(demo03,"线程C");
		t1.setPriority(Thread.MAX_PRIORITY);//优先级最高
		t2.setPriority(Thread.MIN_PRIORITY);//优先级最低
		t3.setPriority(Thread.NORM_PRIORITY);//普通优先级
		t1.start();
		t2.start();
		t3.start();
	}

}

效果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值