文章目录
对多线程的理解
定义:同时对多项任务加以控制
什么是对线程呢?可以理解成一边吃饭,一边听音乐,如果是先吃饭再听音乐或者先听音乐再吃饭,那这就是单线程的,在这里可以把线程理解成一段程序或者一件事。意义: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();
}
}
效果