Java多线程(二)

tech2022-07-07  203

一、线程中的常用操作方法

1.1 Java.lang.Thread类【线程类】

voidstart() 启动线程static ThreadcurrentThread()得到当前正在运行的线程对象StringgetName()返回该线程的名称voidsetName(String name)设置线程名称1. 当没有设置线程名称的时候,系统会赋予线程一个默认的名称“Thread-0,Thread-1…”2. 主线程【主方法的执行线程】的名称默认是“main”intgetPriority() 返回线程的优先级voidsetPriority(int newPriority) 更改线程的优先级

1.2 线程的优先级--就是线程的执行先后

  1. 线程的优先级有10个级别,分别使用整数1~10来表示。 为了方便操作,java将10个级别有规定成3个级别,分别是最低的优先级,中等优先级,最高的优先级,并且将这3个级别封装成了静态常量

static intMAX_PRIORITY 线程可以具有的最高优先级。10static intMIN_PRIORITY线程可以具有的最低优先级。1static intNORM_PRIORITY分配给线程的默认优先级。5

  2. 设置线程的优先级的时候,数字越大优先级越高,数字越小优先级越高。优先级越高并代表就一定会优先执行,只是被优先执行的几率增大,因此不要试图通过控制线程的优先级,来保证某一个线程,总是第一个执行。

  3. 所有线程默认的优先级都是5【中等级别】

例如:

package com.wangxing.test1; public class MyTestThread implements Runnable{ @Override public void run() { //static Thread currentThread()得到当前正在运行的线程对象 Thread threadObj=Thread.currentThread(); //String getName()返回该线程的名称。 String threadName=threadObj.getName(); for(int i=1;i<=10;i++) { System.out.println(threadName+"--i=="+i); } } } package com.wangxing.test1; public class TestMain { public static void main(String[] args) { /* //得到主线程的线程名称 Thread mainThread=Thread.currentThread(); String mainName=mainThread.getName(); // int getPriority() 返回线程的优先级。 int mainpro=mainThread.getPriority(); System.out.println("主线程的名称=="+mainName); System.out.println("主线程的优先级=="+mainpro); */ //创建目标对象 MyTestThread mtth=new MyTestThread(); //创建线程对象 Thread th1=new Thread(mtth); //void setName(String name)设置线程名称 th1.setName("线程A"); //void setPriority(int newPriority) 更改线程的优先级。 th1.setPriority(1); // int getPriority() 返回线程的优先级。 int th_a_pro=th1.getPriority(); System.out.println("线程A的优先级=="+th_a_pro); // void start() 启动线程 th1.start(); //创建线程对象 Thread th2=new Thread(mtth); //void setName(String name)设置线程名称 th2.setName("线程B"); //void setPriority(int newPriority) 更改线程的优先级。 th2.setPriority(Thread.MAX_PRIORITY); // int getPriority() 返回线程的优先级。 int th_b_pro=th2.getPriority(); System.out.println("线程B的优先级=="+th_b_pro); // void start() 启动线程 th2.start(); } }

运行结果:

1.3 守护线程的相关操作方法

  通常情况之下我们所创建的线程都是普通线程,非守护线程,也叫用户线程。   守护线程,也叫精灵线程【当所有用户线程都执行完毕以后,自动结束运行的线程就是守护线程】   特征:当所有用户线程都执行完毕以后,无论守护线程能否可以继续运行,都要立刻停止运行。 例如:不是同年同月同日生,但是一定会同年同月同日死【共死/陪葬】

booleanisDaemon() 测试该线程是否为守护线程voidsetDaemon(boolean on) 将该线程标记为守护线程用户线程

例如:

package com.wangxing.test2; public class TestThread implements Runnable{ @Override public void run() { //static Thread currentThread()得到当前正在运行的线程对象 Thread threadObj=Thread.currentThread(); //String getName()返回该线程的名称。 String threadName=threadObj.getName(); for(int i=1;i<=5;i++) { try { Thread.sleep(400); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(threadName+"--i=="+i); } } } package com.wangxing.test2; public class DoxThread implements Runnable{ @Override public void run() { //static Thread currentThread()得到当前正在运行的线程对象 Thread threadObj=Thread.currentThread(); //String getName()返回该线程的名称。 String threadName=threadObj.getName(); while(true) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(threadName+"是一个守护线程"); } } } package com.wangxing.test2; public class TestMain { public static void main(String[] args) { //创建目标对象 TestThread tth=new TestThread(); DoxThread dth=new DoxThread(); //创建线程对象 Thread th1=new Thread(tth); Thread th2=new Thread(tth); Thread th3=new Thread(dth); //void setDaemon(boolean on) 将该线程标记为守护线程用户线程。 th3.setDaemon(true); //boolean isDaemon() 测试该线程是否为守护线程。 System.out.println("th1是否是守护线程?"+th1.isDaemon()); System.out.println("th2是否是守护线程?"+th2.isDaemon()); System.out.println("th3是否是守护线程?"+th3.isDaemon()); //设置线程的名称 th1.setName("线程A"); th2.setName("线程B"); th3.setName("C线程"); //启动线程 th1.start(); th2.start(); th3.start(); } }

运行结果:

1.4 线程休眠

static voidsleep(long millis) 设置线程休眠【暂停】指定的时间【毫秒】voidinterrupt() 中断线程休眠【暂停】 package com.wangxing.test3; public class MyTestThread implements Runnable{ @Override public void run() { String name=Thread.currentThread().getName(); System.out.println(name+"开始听讲"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name+"进入梦乡。。。。。。"); try { Thread.sleep(10000); } catch (InterruptedException e) { System.out.println(name+"被老师叫醒"); System.out.println(name+"又开始听讲"); try { Thread.sleep(5000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println("下课啦!"); } } } package com.wangxing.test3; public class TestMain { public static void main(String[] args) { System.out.println("上课铃响了"); Thread th=new Thread(new MyTestThread()); th.setName("小明"); th.start(); System.out.println("老师开始上课了"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("老师发现同学睡着啦"); System.out.println("老师走过去叫醒了他"); th.interrupt(); } }

运行结果:

package com.wangxing.test3; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; public class NaoZhong { public static void main(String[] args) { Scanner input=new Scanner(System.in); System.out.println("请设置一个闹钟时间:"); String setTime=input.nextLine(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); boolean flag=true; while(flag) { String newtime=sdf.format(new Date()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(newtime); if(newtime.equals(setTime)) { System.out.println("闹钟响铃!!!!!!"); flag=false; } } } }

运行结果:

1.5 强制线程执行

voidjoin(long millis)等待该线程终止的时间最长为 millis 毫秒。【强制线程执行】

例如:

package com.wangxing.test4; public class MyTestThread implements Runnable{ @Override public void run() { String name=Thread.currentThread().getName(); for(int i=1;i<=10;i++) { try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(name+"--i=="+i); } } } package com.wangxing.test4; public class TestMain { public static void main(String[] args) { Thread th=new Thread(new MyTestThread()); th.setName("Test线程"); th.start(); String mainname=Thread.currentThread().getName(); for(int j=1;j<=10;j++) { try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(mainname+"--j=="+j); if(j==5) { try { th.join(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

运行结果:

二、线程的生命周期

  1、线程的生命周期就是线程从一开始创建,到run方法执行完毕以后的状态变化。[状态之间的切换]

  2、线程的生命周期几种状态【1、新建状态 2、就绪状态 3、运行状态 4.阻塞状态 5.死亡状态】

  创建状态:通过new的方式创建出线程对象,此时线程就进入到创建状态【新建状态】。     新建状态的线程是不能运行。

  就绪状态:新建状态的线程调用strat方法之后就会进入就绪状态。      就绪状态的线程具备执行能力,但是没有cpu资源。【万事具备只差cpu】.

  运行状态:就绪状态的线程得到cpu资源开始执行run方法,此时这个线程就是运行状态。     运行状态的线程当cpu切换到其他线程时候,本线程就再一次进入就绪状态。

  阻塞状态:运行状态的线程调用sleep/wait方法…此时线程进入阻塞状态。     处于阻塞状态的线程的休眠时间到/调用notify方法/notifyAll方法在此时线程进入就绪状态,     从就绪状态中得到cpu资源从而进入运行状态。

  死亡状态:运行状态的线程run方法运行结束/线程执行过程中遇到异常/调用stop方法此时 线程就进入到死亡状态。     死亡状态的线程是不能运行,除非再一次使用strat方法重新启动运行。

总结

最新回复(0)