多线程常用操作方法
线程的命名与取得
由于多线程的状态不确定,所以线程的名字就成为了唯一的分辨标记,则在定义线程名称时一定要在线程启动之前设置名字,尽量不要重名,且尽量不要为已经启动动的线程修改名字。
由于线程状态的不确定,所以每次可以操作的都是正在执行run()方法的线程,那么取得当前线程对象的方法为:public static Thread current Thread()。
例:观察线程的命名
package Project.Study.Multithreading;
class MyTread4 implements Runnable{
@Override
public void run(){
System.out.println(Thread.currentThread().getName());//使用currentThread()取得当前线程对象后再取得具体的线程名字
}
}
public class Test4 {
public static void main(String [] args) throws Exception{
MyTread4 mt=new MyTread4();
new Thread(mt,"自己的线程A").start();
new Thread(mt).start();
new Thread(mt,"自己的线程B").start();
new Thread(mt).start();
new Thread(mt).start();
}
}
//结果:
//自己的线程A
//Thread-1
//自己的线程B
//Thread-0
//Thread-2
例:取得线程名字
package Project.Study.Multithreading;
class MyTread4 implements Runnable{
@Override
public void run(){
System.out.println(Thread.currentThread().getName());//使用currentThread()取得当前线程对象后再取得具体的线程名字
}
}
public class Test4 {
public static void main(String [] args) throws Exception{
MyTread4 mt=new MyTread4();
new Thread(mt,"自己的线程A").start();
new Thread(mt).start();
mt.run();
}
}
//结果:
//main
//自己的线程A
//Thread-0
通过本程序我们可以发现主方法本身也属于一个线程。
每一个JVM进程都至少启动以下两个线程:
1.main线程:程序的主要执行,以及启动子程序;
2.gc线程:负责垃圾收集。
线程的休眠
线程的休眠指的是让程序的执行速度变慢一些,在Thread类中线程的休眠操作方法为:public static void sleep(long millis)throws InterruptedException,设置的休眠单位是毫秒(ms)。
例:观察休眠特点
package Project.Study.Multithreading;
class MyThread5 implements Runnable{
@Override
public void run(){
for (int x=0;x<10;x++){
try {
Thread.sleep(1000); //每次执行休眠1s
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+",x="+x);
}
}
}
public class Test5 {
public static void main(String []args){
MyThread5 mt1=new MyThread5();
MyThread5 mt2=new MyThread5();
MyThread5 mt3=new MyThread5();
new Thread(mt1,"自己的线程对象A").start();
new Thread(mt2,"自己的线程对象B").start();
new Thread(mt3,"自己的线程对象C").start();
}
}
//结果:
//自己的线程对象B,x=0
//自己的线程对象A,x=0
//自己的线程对象C,x=0
//自己的线程对象A,x=1
//自己的线程对象B,x=1
//自己的线程对象C,x=1
//自己的线程对象B,x=2
//自己的线程对象A,x=2
//自己的线程对象C,x=2
//...
//自己的线程对象C,x=9
//自己的线程对象B,x=9
//自己的线程对象A,x=9
上面这个程序的结果是三个三个输出的(其实是一种错觉),每隔一秒输出三个线程对象,由于线程切换速度过快,所以会有一种所有线程同时进入run()方法中的感觉,而实际上是有先后差距的。
线程优先级
在Java的线程操作中,优先级高的线程就可能先被执行。线程的优先级如下图所示:
线程优先级操作
No. | 方法或常量 | 类型 | 描述 |
---|---|---|---|
1 | public static final int MAX_PRIORITY | 常量 | 最高优先级,数值为10 |
2 | public static final int NORM_PRIORITY | 常量 | 中等优先级,数值为5 |
3 | public static final int MIN_PRIORITY | 常量 | 最低优先级,数值为1 |
4 | public final void setPriority(int new Priority) | 普通 | 设置线程优先级 |
5 | public final int getPriority(); | 普通 | 取得线程优先级 |
例:设置线程优先级
package Project.Study.Multithreading;
class MyThread6 implements Runnable{
@Override
public void run(){
for(int x=0;x<20;x++){
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+",x="+x);
}
}
}
public class Test6 {
public static void main(String [] args){
MyThread6 mt1 = new MyThread6();
Thread t1 = new Thread(mt1,"自己的线程对象A");
Thread t2= new Thread(mt1,"自己的线程对象B");
Thread t3=new Thread(mt1,"自己的线程对象C");
t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t3.setPriority(Thread.NORM_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
//结果:
//自己的线程对象C,x=0
//自己的线程对象A,x=0
//自己的线程对象B,x=0
//自己的线程对象A,x=1
//自己的线程对象C,x=1
//自己的线程对象B,x=1
//自己的线程对象C,x=2
//自己的线程对象A,x=2
//自己的线程对象B,x=2
//自己的线程对象B,x=3
//自己的线程对象C,x=3
//自己的线程对象A,x=3
//自己的线程对象B,x=4
//自己的线程对象A,x=4
//自己的线程对象C,x=4
//...
//自己的线程对象C,x=19
//自己的线程对象B,x=19
//自己的线程对象A,x=19
从运行结果可以看出,线程的执行顺序不一定按照设定的优先级执行,这是因为线程不一定能获得cpu资源。
探究:主方法的优先级
public class Test6 {
public static void main(String [] args){
System.out.println(Thread.currentThread().getPriority());
}
}
//结果:
//5
由此可知,主方法的优先级为5