Java多线程常用操作方法
取得和设置线程名称
在Thread类中,可以通过getName()方法取得线程的名称,通过setName()设置线程的名称
线程的名称一般在启动线程前设置,但也允许为已经运行的线程设置名称,允许两个Thread对象有相同的名字,但为了清洗,应该尽量避免这种情况的发送
如果程序并没有为线程指定名字,则系统会自动为线程分配一个名称
事例
定义一个类
package com.qn.thread;
public class MyThread implements Runnable{
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("当前线程的名字:"+Thread.currentThread().getName()+"运行 i"+i);
}
}
}
在test类中进行测试
package com.qn.test;
import com.qn.thread.MyThread;
public class test {
public static void main(String[] args) {
MyThread t=new MyThread();
Thread thread=new Thread(t);
Thread thread1=new Thread(t,"qining");//手动设置线程名称
thread.start();
thread1.start();
}
}
结果
结果知道指定的名称会自动出现,如果没有指定名称线程会自动编号的方式完成,安装 Thread-0,Thread-1 依次编号,实际上肯定在类中存在一个static 属性,用于记录编号
取得当前线程 可以通过currentThread()方法取得当前正在运行的线程对象
下面在test类中测试
package com.qn.test;
import com.qn.thread.MyThread;
public class test {
public static void main(String[] args) {
MyThread t=new MyThread();//实例化Runnable线程子类对象
Thread thread1=new Thread(t,"qining");//手动设置线程名称
thread1.start();
t.run();//直接调用Run方法
}
}
结果
此时程序运行的结果,程序中由主方法直接通过线程对象调用run()方法,所以输出的结果中包含一个“main”,此线程是由“t.run()”因为调用此语句是由主方法完成的,也就是说实际上主方法本身也是一个线程-主线程
既然主方法是由线程的形式出现的,那么java运行时候启动多少线程呢?
至少启动两个
每当java程序执行的时候,实际上都会启动一个JVM,每一个JVM实际上就是操作系统中启动一个进程
java中本身还具备了垃圾回收机制,所以java运行时至少启动两个线程,主线程、GC
判断线程是否还在执行
isAlive()
package com.qn.test;
import com.qn.thread.MyThread;
public class test {
public static void main(String[] args) {
MyThread t=new MyThread();//实例化Runnable线程子类对象
Thread thread1=new Thread(t,"qining");//手动设置线程名称
System.out.println("线程开始执行之前----->"+thread1.isAlive());//判断线程是否启动
thread1.start();
System.out.println("线程开始执行之后----->"+thread1.isAlive());
for (int i = 0; i < 3; i++) {
System.out.println("主线程main运行----->"+i);
}
System.out.println("线程开始执行之后----->"+thread1.isAlive());
}
}
结果
线程的强制运行
在线程操作中,可以使用join()方法让一个线程强制运行,线程强制运行期间,其他线程无法运行,必须等待此线程完成之后才可以继续执行
事例
package com.qn.test;
import com.qn.thread.MyThread;
public class test {
public static void main(String[] args) {
MyThread t=new MyThread();//实例化Runnable线程子类对象
Thread thread1=new Thread(t,"qining");//手动设置线程名称
System.out.println("线程开始执行之前----->"+thread1.isAlive());//判断线程是否启动
thread1.start();
System.out.println("线程开始执行之后----->"+thread1.isAlive());
for (int i = 0; i < 50; i++) {
if(i>10){
try {
thread1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("main线程运行:"+i);
}
}
}
结果
线程的休眠
使用休眠可以让线程暂停执行
事例
在类中让线程休眠5000
package com.qn.thread;
public class MyThread implements Runnable{
public void run() {
for (int i = 0; i < 50; i++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("当前线程的名字:"+Thread.currentThread().getName()+"运行 ,i="+i);
}
}
}
在test类中进行测试
package com.qn.test;
import com.qn.thread.MyThread;
public class test {
public static void main(String[] args) {
MyThread t=new MyThread();//实例化Runnable线程子类对象
Thread thread1=new Thread(t,"qining");//手动设置线程名称
thread1.start();
}
}
结果
此时每次执行都会休眠5秒
线程的终断
一个线程可以被另一个线程中断其操作的状态,使用interrupt()方法完成
事例
定义一个MyThread类
package com.qn.thread;
public class MyThread implements Runnable{
public void run() {
System.out.println("1.进入run()方法");
try {
Thread.sleep(2000);
System.out.println("2.已经完成休眠");
} catch (InterruptedException e) {
System.out.println("3.休眠被中断了");
}
System.out.println("4.run()方法正常结束");
}
}
在test类中测试
package com.qn.test;
import com.qn.thread.MyThread;
public class test1 {
public static void main(String[] args) {
MyThread t=new MyThread();//实例化Runnable线程子类对象
Thread thread1=new Thread(t,"qining");//手动设置线程名称
thread1.start();
thread1.interrupt();
}
}
结果
设置后台线程
在java中只要一个程序没有执行完(一个线程在运行),则整个java进程不会消失,所以,此时可以设置一个后台线程,
这样即使java进程结束了,此后台线程依然会继续执行,要实现这样的操作直接使用setDaemon()方法
事例 定义一个类
package com.qn.thread;
public class MyThread implements Runnable{
public void run() {
while(true){
System.out.println(Thread.currentThread().getName());
}
}
}
在test类中进行测试
package com.qn.test;
import com.qn.thread.MyThread;
public class test2 {
public static void main(String[] args) {
MyThread t=new MyThread();//实例化Runnable线程子类对象
Thread thread1=new Thread(t,"qining");//手动设置线程名称
thread1.setDaemon(true);//这只线程在后台执行
thread1.start();
}
}
结果
虽然是死循环但是此时控制台 不在运行而是在虚拟机后台执行
在java中只要一个程序没有执行完(一个线程在运行),则整个java进程不会消失,所以,此时可以设置一个后台线程,这样即使java进程结束了,此后台线程依然会继续执行,要实现这样的操作直接使用setDaemon()方法
最高优先级 Thread.MAX_PRIORITY
中等优先级 Thread.NORM_PRIORITY
最低优先级 Thread.MIN_PRIORITY
事例 定义一个类
package com.qn.thread;
public class MyThread implements Runnable{
public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("当前线程的名字:"+Thread.currentThread().getName()+"运行 ,i="+i);
}
}
}
在test类中进行测试
package com.qn.test;
import com.qn.thread.MyThread;
public class test3 {
public static void main(String[] args) {
Thread thread1=new Thread(new MyThread(),"线程A");//手动设置线程名称
Thread thread2=new Thread(new MyThread(),"线程B");//手动设置线程名称
Thread thread3=new Thread(new MyThread(),"线程C");//手动设置线程名称
thread1.setPriority(Thread.MIN_PRIORITY);
thread2.setPriority(Thread.MAX_PRIORITY);
thread3.setPriority(Thread.NORM_PRIORITY);
thread1.start();
thread2.start();
thread3.start();
}
}
结果
这方法的优先级是什么
事例
package com.qn.test;
import com.qn.thread.MyThread;
public class test4 {
public static void main(String[] args) {
System.out.println("主方法的优先级是:"+Thread.currentThread().getPriority());
}
}
结果
5相当于是中等级优先级
线程的礼让
在线程操作中,也可以使用yield()方法将一个线程的操作暂停时让给其他线程执行
事例 定义一个类
package com.qn.thread;
public class MyThread implements Runnable{
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"运行 ,i="+i);
if (i==3) {
System.out.print("线程礼让:");
Thread.yield();
}
}
}
}
在test类中进行测试
package com.qn.test;
import com.qn.thread.MyThread;
public class test4 {
public static void main(String[] args) {
MyThread my=new MyThread();
Thread t1=new Thread(my,"线程A");
Thread t2=new Thread(my,"线程B");
t1.start();
t2.start();
}
}
结果