关于Java多线程--------(2,线程常用操作方法)

时间:2022-01-29 15:54:13

1,设置和获取线程名称

2,线程的强制运行

3,线程的休眠

4,线程的礼让

5,线程的中断操作

在多线程中,所有的线程操作方法,基本上都是在Thread类中。
常用的线程操作方法有:
1

接收Runnable接口子类对象,实例化Thread对象
Allocates a new Thread object.

Thread(Runnable target)

2

接收Runnable接口子类对象,实例化Thread对象,并设置线程名称Allocates a new Thread object.

Thread(Runnable target, String name)

3

实例化线程对象,并设置线程名称
Allocates a new Thread object.

Thread(String name)

4

返回目前正在执行的线程
Returns a reference to the currently executing thread object.

public static Thread currentThread()

5

返回线程名称
Returns this thread's name.

public final String getName()

6

返回线程的优先级
Returns this thread's priority.

public final int getPriority()

7

判断目前线程是否被中断
Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method.

public boolean isInterrupted()

8

判断线程是否在活动
Tests if this thread is alive. A thread is alive if it has been started and has not yet died.

public final boolean isAlive()

9

等待线程死亡
Waits for this thread to die.
An invocation of this method behaves in exactly the same way as the invocation

public final void join()
throws InterruptedException

10

等待millis毫秒后,线程死亡
Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.

This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

public final void join(long millis)
throws InterruptedException

11

执行线程
If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.

Subclasses of Thread should override this method.

public void run()

12

设定线程名称
Changes the name of this thread to be equal to the argument name.

First the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException.

public final void setName(String name)

13

设定线程的优先值
Changes the priority of this thread.
First the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException.

Otherwise, the priority of this thread is set to the smaller of the specified newPriority and the maximum permitted priority of the thread's thread group.

public final void setPriority(int newPriority)

14

使目前正在运行的线程休眠millis毫秒
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.

public static void sleep(long millis)
throws InterruptedException

15

开始执行线程
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.

The result is that two threads are running concurrently:
the current thread (which returns from the call to the start method) and the other thread (which executes its run method).

It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.

public void start()

16

将目前仍在执行的线程暂停,允许其他线程执行
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.

Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect.

It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.

public static void yield()

17

将一个线程设置成后台运行
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.

This method must be invoked before the thread is started.

public final void setDaemon(boolean on)

18

更改线程优先级
Changes the priority of this thread.
First the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException.

Otherwise, the priority of this thread is set to the smaller of the specified newPriority and the maximum permitted priority of the thread's thread group.

public final void setPriority(int newPriority)

1,线程名称

在Thread类中,可以通过getName()方法取得线程的名称,通过setName()方法设置线程的名称。
线程的名称一般在启动线程前设置,但是也允许为已经运行的线程设置名称。允许两个Thread对象有相同的名字,但是为了清晰,应该精良避免这种情况的发生。
另外,如果程序并没有为线程指定名称,则系统会自动为线程分配一个名称。

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName()
+ "运行,i = " + i) ; // 取得当前线程的名字
}
}
};
public class ThreadNameDemo{
public static void main(String args[]){
MyThread mt = new MyThread() ; // 实例化Runnable子类对象
new Thread(mt).start() ; // 系统自动设置线程名称
new Thread(mt,"线程-A").start() ; // 手工设置线程名称
new Thread(mt,"线程-B").start() ; // 手工设置线程名称
new Thread(mt).start() ; // 系统自动设置线程名称
new Thread(mt).start() ; // 系统自动设置线程名称
}
};

运行结果:
关于Java多线程--------(2,线程常用操作方法)

发现,指定的名称会出现,如果没有指定名称,会自动编号,按照Thread-0,Thread-1。。。一次编号,实际上,肯定在Thread类中有一个static属性的变量,用于记录编号。

当前线程currentThread

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName()
+ "运行,i = " + i) ; // 取得当前线程的名字
}
}
};
public class CurrentThreadDemo{
public static void main(String args[]){
MyThread mt = new MyThread() ; // 实例化Runnable子类对象
new Thread(mt,"线程").start() ; // 启动线程
mt.run() ; // 直接调用run()方法
}
};

运行结果:
关于Java多线程--------(2,线程常用操作方法)

程序中,通过线程对象直接调用run方法,输出的结果是“”main“”,因为调用“mt.run()”是由主方法完成的,也就是说实际上主方法本身也是一个线程——-主线程。

问题来了

既然主方法都是以线程的形式出现的,那么Java运行时,到底开启了多少个线程呢?
其实简单——-:至少启动两个线程,因为,每当Java程序执行的时候,都会启动一个jvm,每一个jvm实际上就是在操作系统中启动了一个进程。Java本身具备垃圾收集机制 ,所以Java运行时至少启动了两个线程:主线程、gc

2,判断线程是否还在运行

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName()
+ "运行,i = " + i) ; // 取得当前线程的名字
}
}
};
public class ThreadAliveDemo{
public static void main(String args[]){
MyThread mt = new MyThread() ; // 实例化Runnable子类对象
Thread t = new Thread(mt,"线程"); // 实例化Thread对象
System.out.println("线程开始执行之前 --> " + t.isAlive()) ; // 判断是否启动
t.start() ; // 启动线程
System.out.println("线程开始执行之后 --> " + t.isAlive()) ; // 判断是否启动
for(int i=0;i<3;i++){
System.out.println(" main运行 --> " + i) ;
}
// 以下的输出结果不确定
System.out.println("代码执行之后 --> " + t.isAlive()) ; // 判断是否启动

}
};

这个输出结果,其实并不是一成不变的,这个输出结果是变化的,因为连个线程谁先执行完毕,是不确定的,谁先强占到CPU资源是不确定的。
关于Java多线程--------(2,线程常用操作方法)

关于Java多线程--------(2,线程常用操作方法)

2,线程的强制运行

强制运行,join方法,让当前的线程优先执行,其他的线程都靠边站,这个线程执行结束了,再执行其他线程,但是要注意的是,这个方法是使用了throws修饰的,需要捕捉异常并进行处理;

想起一个场面,一个送情报的大唐情报员,快马加鞭,“急报····急报—-快开城门,闲杂人等避让”。。。。。。

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
for(int i=0;i<50;i++){
System.out.println(Thread.currentThread().getName()
+ "运行,i = " + i) ; // 取得当前线程的名字
}
}
};
public class ThreadJoinDemo{
public static void main(String args[]){
MyThread mt = new MyThread() ; // 实例化Runnable子类对象
Thread t = new Thread(mt,"线程"); // 实例化Thread对象
t.start() ; // 启动线程
for(int i=0;i<50;i++){
if(i>10){
try{
t.join() ; // 线程强制运行
}catch(InterruptedException e){}
}
System.out.println("Main线程运行 --> " + i) ;
}
}
};

关于Java多线程--------(2,线程常用操作方法)

关于Java多线程--------(2,线程常用操作方法)

3,线程的休眠

使用休眠,可以让线程暂停执行。使用Thread.sleep()方法即可。值得注意的是,sleep使用了static修饰,同时也使用了throws修饰,需要在调用处捕捉异常进行处理。

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
for(int i=0;i<50;i++){
try{
Thread.sleep(500) ; // 线程休眠
}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()
+ "运行,i = " + i) ; // 取得当前线程的名字
}
}
};
public class ThreadSleepDemo{
public static void main(String args[]){
MyThread mt = new MyThread() ; // 实例化Runnable子类对象
Thread t = new Thread(mt,"线程"); // 实例化Thread对象
t.start() ; // 启动线程
}
};

每一次执行线程打印的时候,都会暂停500ms然后再打印,执行代码。

4,线程的中断

让他永远停止,有点心狠了哦~

一个线程可以被另外一个线程中断其操作的状态,使用的interrupt()方法即可中断其运行状态。

比如说,一个线程正在休眠,想要打断其休眠状态。

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
System.out.println("1、进入run()方法") ;
try{
Thread.sleep(10000) ; // 线程休眠10秒
System.out.println("2、已经完成了休眠") ;
}catch(InterruptedException e){
System.out.println("3、休眠被终止") ;
return ; // 返回调用处
}
System.out.println("4、run()方法正常结束") ;
}
};
public class ThreadInterruptDemo{
public static void main(String args[]){
MyThread mt = new MyThread() ; // 实例化Runnable子类对象
Thread t = new Thread(mt,"线程"); // 实例化Thread对象
t.start() ; // 启动线程
try{
Thread.sleep(2000) ; // 线程休眠2秒
}catch(InterruptedException e){
System.out.println("3、休眠被终止") ;
}
t.interrupt() ; // 中断线程执行
}
};

5,后台线程在Java中,只要前台有一个程序没有执行完(一个线程在运行),则整个Java的进程不会消失,多以,此时可以设置一个后台线程,这样一来,即使Java进程结束了,此后台线程依然会继续执行。

要想实现这样的操作,直接使用setDaemon()方法即可。

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
while(true){
System.out.println(Thread.currentThread().getName() + "在运行。") ;
}
}
};
public class ThreadDaemonDemo{
public static void main(String args[]){
MyThread mt = new MyThread() ; // 实例化Runnable子类对象
Thread t = new Thread(mt,"线程"); // 实例化Thread对象
t.setDaemon(true) ; // 此线程在后台运行
t.start() ; // 启动线程
}
};

6,线程的优先级,在Java的线程操作中,所有的线程在运行前都会保持在就绪状态,那么此时,哪个线程的优先级高,哪个线程就有可能会先被执行。

关于Java多线程--------(2,线程常用操作方法)

优先级越高的线程,越有可能先被执行。
关于Java多线程--------(2,线程常用操作方法)

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
for(int i=0;i<5;i++){
try{
Thread.sleep(500) ; // 线程休眠
}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()
+ "运行,i = " + i) ; // 取得当前线程的名字
}
}
};
public class ThreadPriorityDemo{
public static void main(String args[]){
Thread t1 = new Thread(new MyThread(),"线程A") ; // 实例化线程对象
Thread t2 = new Thread(new MyThread(),"线程B") ; // 实例化线程对象
Thread t3 = new Thread(new MyThread(),"线程C") ; // 实例化线程对象
t1.setPriority(Thread.MIN_PRIORITY) ; // 优先级最低
t2.setPriority(Thread.MAX_PRIORITY) ; // 优先级最大
t3.setPriority(Thread.NORM_PRIORITY) ; // 优先级普通
t1.start() ; // 启动线程
t2.start() ; // 启动线程
t3.start() ; // 启动线程
}
};

优先级高到低,
关于Java多线程--------(2,线程常用操作方法)

主方法的优先级
主方法的线程优先级是5,主方法同样是一个线程对象。

public class MainPriorityDemo{
public static void main(String args[]){
System.out.println("主方法的优先级:" +
Thread.currentThread().getPriority()) ; // 取得主方法的优先级
System.out.println("MAX_PRIORITY = " + Thread.MAX_PRIORITY) ;
System.out.println("NORM_PRIORITY = " + Thread.NORM_PRIORITY) ;
System.out.println("MIN_PRIORITY = " + Thread.MIN_PRIORITY) ;
}
};

关于Java多线程--------(2,线程常用操作方法)

7,线程礼让可以使用yieid()方法,将一个线程的操作暂时让给其他线程执行。

class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
for(int i=0;i<5;i++){
try{
Thread.sleep(500) ;
}catch(Exception e){}
System.out.println(Thread.currentThread().getName()
+ "运行,i = " + i) ; // 取得当前线程的名字
if(i==2){
System.out.print("线程礼让:") ;
Thread.currentThread().yield() ; // 线程礼让
}
}
}
};
public class ThreadYieldDemo{
public static void main(String args[]){
MyThread my = new MyThread() ; // 实例化MyThread对象
Thread t1 = new Thread(my,"线程A") ;
Thread t2 = new Thread(my,"线程B") ;
t1.start() ;
t2.start() ;
}
};

关于Java多线程--------(2,线程常用操作方法)

总结:
线程的基本操作方法,都是从Thread类中找出来的,查找Thread类即可找到这些操作。