线程常用操作方法

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

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(); //系统自动设置线程名称
}
}

class MyThread implements Runnable{ //实现Runnable接口
public void run() { //覆写run方法
for(int i = 0;i < 3;i++) {
System.out.println(Thread.currentThread().getName() + “运行,i = ” + i);
}
}
}
程序运行效果:
Thread-0运行,i = 0
线程B运行,i = 0
线程B运行,i = 1
线程B运行,i = 2
线程A运行,i = 0
线程A运行,i = 1
Thread-0运行,i = 1
Thread-0运行,i = 2
Thread-2运行,i = 0
Thread-2运行,i = 1
线程A运行,i = 2
Thread-1运行,i = 0
Thread-2运行,i = 2
Thread-1运行,i = 1
Thread-1运行,i = 2

从执行效果来看.制定的名称会自动出现,如果没有指定会发现线程使用自动编号的方式完成。按照:Thread-0,Thread-1依次编号,实际上肯定在类中存在一个static属性,用于记录编号

当前线程
程序可以通过currentThread()方法取得当前正在运行的程序对象

public class CurrentThreadDemo {
public static void main(String[] args) {
    MyThread mt = new MyThread();  //实例化Runnable子类对象
    new Thread(mt,"线程").start();  //启动线程
    mt.run();   //直接调用run()方法

}

}

class MyThread01 implements Runnable{ //实现Runnable接口
public void run() { //覆写run方法
for(int i = 0;i < 3;i++) {
System.out.println(Thread.currentThread().getName() + “运行,i = ” + i);
}
}
程序运行结果:
main运行,i = 0
线程运行,i = 0
main运行,i = 1
线程运行,i = 1
main运行,i = 2
线程运行,i = 2
此时发现,程序中由主方法直接通过线程对象调用里面的run()方法,所以输出的结果中包含了一个“main”,此线程就是由“mt.run()”,因为调用此语句是由主方法完成的,也就是说实际上主方法本身也是一个线程–主线程

问题:既然主方法都是以线程的形式出现的,那么java运行时到底启动了多少个线程呢
回答:至少两个
从之前学习到的知识来看,每当java程序执行的时候,实际上都会启动一个jvm,每一个jvm实际上就是操作系统中启动了一个进程。java中本身具备了垃圾收集机制,所以java运行时至少启动了两个线程:主线程,GC(垃圾回收机制)

判断线程是否启动
public class ThreadAliveDemo {
public static void main(String[] args) {
MyThread02 mt = new MyThread02(); //实例化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());

}

}

class MyThread02 implements Runnable{ //实现Runnable接口
public void run() { //覆写run方法
for(int i = 0;i < 3;i++) {
System.out.println(Thread.currentThread().getName() + “运行,i = ” + i);
}
}
}
运行结果:线程开始之前–>false
线程开始之后–>true
main运行–>0
main运行–>1
main运行–>2
代码执行之后–>true

线程的强制运行
在线程操作中,可以使用join()方法让一个线程强制运行,线程强制运行期间,其他线程无法运行,必须等待此线程完成之后才可以继续执行

public class ThreadJoinDemo {
public static void main(String[] args) {
MyThread03 mt = new MyThread03(); //实例化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);
        }
    }

}

class MyThread03 implements Runnable{ //实现Runnable接口
public void run() { //覆写run方法
for(int i = 0;i < 50;i++) {
System.out.println(Thread.currentThread().getName() + “运行,i = ” + i);
}
}
}
程序运行结果:
Main线程运行 –>0
线程运行,i = 0
Main线程运行 –>1
线程运行,i = 1
Main线程运行 –>2
Main线程运行 –>3
Main线程运行 –>4
Main线程运行 –>5
Main线程运行 –>6
Main线程运行 –>7
Main线程运行 –>8
Main线程运行 –>9
线程运行,i = 2
Main线程运行 –>10
线程运行,i = 3
线程运行,i = 4
线程运行,i = 5
线程运行,i = 6
线程运行,i = 7
线程运行,i = 8
线程运行,i = 9
线程运行,i = 10
线程运行,i = 11
线程运行,i = 12
线程运行,i = 13
线程运行,i = 14
线程运行,i = 15
线程运行,i = 16
线程运行,i = 17
线程运行,i = 18
线程运行,i = 19
线程运行,i = 20
线程运行,i = 21
线程运行,i = 22
线程运行,i = 23
线程运行,i = 24
线程运行,i = 25
线程运行,i = 26
线程运行,i = 27
线程运行,i = 28
线程运行,i = 29
线程运行,i = 30
线程运行,i = 31
线程运行,i = 32
线程运行,i = 33
线程运行,i = 34
线程运行,i = 35
线程运行,i = 36
线程运行,i = 37
线程运行,i = 38
线程运行,i = 39
线程运行,i = 40
线程运行,i = 41
线程运行,i = 42
线程运行,i = 43
线程运行,i = 44
线程运行,i = 45
线程运行,i = 46
线程运行,i = 47
线程运行,i = 48
线程运行,i = 49
Main线程运行 –>11
Main线程运行 –>12
Main线程运行 –>13
Main线程运行 –>14
Main线程运行 –>15
Main线程运行 –>16
Main线程运行 –>17
Main线程运行 –>18
Main线程运行 –>19
Main线程运行 –>20
Main线程运行 –>21
Main线程运行 –>22
Main线程运行 –>23
Main线程运行 –>24
Main线程运行 –>25
Main线程运行 –>26
Main线程运行 –>27
Main线程运行 –>28
Main线程运行 –>29
Main线程运行 –>30
Main线程运行 –>31
Main线程运行 –>32
Main线程运行 –>33
Main线程运行 –>34
Main线程运行 –>35
Main线程运行 –>36
Main线程运行 –>37
Main线程运行 –>38
Main线程运行 –>39
Main线程运行 –>40
Main线程运行 –>41
Main线程运行 –>42
Main线程运行 –>43
Main线程运行 –>44
Main线程运行 –>45
Main线程运行 –>46
Main线程运行 –>47
Main线程运行 –>48
Main线程运行 –>49

线程的休眠
在程序中允许一个线程进行暂时的休眠,直接使用Thread.sleep()方法即可
public class ThreadSleepDemo {
public static void main(String[] args) {
MyThread04 mt = new MyThread04(); //实例化Runnable子类对象
Thread t = new Thread(mt,”线程”); //实例化Thread对象

    t.start(); //启动线程

}

}

class MyThread04 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);
}
}
}

线程的中断
当一个线程运行的时候,另外一个线程可以直接通过interrupt()方法,中断其运行状态
public class ThreadInterruptDemo {
public static void main(String[] args) {
MyThread05 mt = new MyThread05(); //实例化Runnable子类对象
Thread t = new Thread(mt,”线程”); //实例化Thread对象

    t.start(); //启动线程
    try {
        Thread.sleep(10000);    

    }catch(InterruptedException e) {
        System.out.println("3.休眠被终止");
    }
    t.interrupt();//中断线程执行

}

}

class MyThread05 implements Runnable{ //实现Runnable接口
public void run() { //覆写run方法
System.out.println(“1.进入run()方法”);

        try {
            Thread.sleep(2000);   
            System.out.println("2.已经完成休眠");
        }catch(InterruptedException e) {
            System.out.println("3.休眠被终止");
            return ;   //返回调用处;
        }
        System.out.println("4.run方法正常结束");
    }
}

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

public class ThreadDaemonDemo {
public static void main(String[] args) {
MyThread06 mt = new MyThread06(); //实例化Runnable子类对象
Thread t = new Thread(mt,”线程”); //实例化Thread对象

    t.setDaemon(true);  //线程在后台运行
    t.start();              //启动线程
}

}

class MyThread06 implements Runnable{ //实现Runnable接口
public void run() { //覆写run方法
while(true) {
System.out.println(Thread.currentThread().getName() + “在运行”);
}
}

线程的优先级
在java的线程操作中,所有的线程在运行前都会保持就绪状态,那么此时,谁的优先级高,那个线程就有可能被先执行
最高优先级:MAX_PRIORTY
中等优先级:NORM_PRIORTY
最低优先级:MIN_PRIORTY

public class ThreadPriorityDemo {
public static void main(String[] args) {
Thread t1 = new Thread(new MyThread07(),”线程A”);
Thread t2 = new Thread(new MyThread07(),”线程B”);
Thread t3 = new Thread(new MyThread07(),”线程C”);

    t1.setPriority(Thread.MIN_PRIORITY);
    t2.setPriority(Thread.MAX_PRIORITY);
    t3.setPriority(Thread.NORM_PRIORITY);

    t1.start();
    t2.start();
    t3.start();
}

}

class MyThread07 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);
}
}
}
运行结果:
线程B运行,i = 0
线程C运行,i = 0
线程A运行,i = 0
线程B运行,i = 1
线程C运行,i = 1
线程A运行,i = 1
线程B运行,i = 2
线程C运行,i = 2
线程A运行,i = 2
线程B运行,i = 3
线程C运行,i = 3
线程A运行,i = 3
线程B运行,i = 4
线程C运行,i = 4
线程A运行,i = 4

主方法优先级
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(“MIN_PRIORITY = ” + Thread.MIN_PRIORITY);
System.out.println(“NORM_PRIORITY = ” + Thread.NORM_PRIORITY);
}
}

运行结果:
主方法优先级:5
MAX_PRIORITY = 10
MIN_PRIORITY = 1
NORM_PRIORITY = 5

线程礼让
public class ThreadYieldDemo {
public static void main(String[] args) {
MyThread10 my = new MyThread10();

    Thread t1 = new Thread(my,"线程A");
    Thread t2 = new Thread(my,"线程B");

    t1.start();
    t2.start();
}

}

class MyThread10 implements Runnable{
public void 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.println(“线程礼让”);
Thread.currentThread().yield();
}
}
}
}
运行结果:
线程A运行,i = 0
线程B运行,i = 0
线程A运行,i = 1
线程B运行,i = 1
线程A运行,i = 2
线程B运行,i = 2
线程礼让
线程礼让
线程B运行,i = 3
线程A运行,i = 3
线程B运行,i = 4
线程A运行,i = 4

总结
在本章中重点只是阐述了线程的基本操作方法。对于这些操作,实际上都是从Thread类中找出来的,用的时候只需要查找Thread类即可
对于休眠的操作最好记住,因为以后还要用

实例要求
要求:设计一个线程的操作类,要求可以产生三个线程对象,并可以设置三个线程的休眠时间,如下所示:
线程A休眠10秒
线程B休眠20秒
线程C休眠30秒

使用Thread类完成

public class ThreadSleep {
public static void main(String[] args) {
MyThread123 t1 = new MyThread123(“线程A”,10000);
MyThread123 t2 = new MyThread123(“线程B”,20000);
MyThread123 t3 = new MyThread123(“线程C”,30000);

    t1.start();
    t2.start();
    t3.start();

}

}

class MyThread123 extends Thread{
private int time;

public MyThread123(String name,int time) {
    super(name);   //设置线程名称
    this.time = time;   //设置休眠时间
}

public void run() {
    try {
        Thread.sleep(this.time);   //指定休眠时间
    }catch(InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "线程,休眠" + this.time + "毫秒");
}

}
运行结果:
线程A线程,休眠10000毫秒
线程B线程,休眠20000毫秒
线程C线程,休眠30000毫秒

使用Runnable接口
如果使用Runnable接口,则类中是没有线程名称存在的,所以应该单独建立一个name属性,以保证线程名称的存在

public class RunnableSleep {
public static void main(String[] args) {
MyThread010 mt1 = new MyThread010(“线程A”,10000);
MyThread010 mt2 = new MyThread010(“线程B”,20000);
MyThread010 mt3 = new MyThread010(“线程C”,30000);

    new Thread(mt1).start();
    new Thread(mt2).start();
    new Thread(mt3).start();


}

}

class MyThread010 implements Runnable{
private String name;
private int time;

public MyThread010(String name,int time) {
    this.name = name;
    this.time = time;
}
public void run() {
    try {
        Thread.sleep(this.time);
    }catch(InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(this.name + "线程,休眠" + this.time + "毫秒");
}

}
运行结果:
线程A线程,休眠10000毫秒
线程B线程,休眠20000毫秒
线程C线程,休眠30000毫秒

猜你喜欢

转载自blog.csdn.net/weixin_43149344/article/details/82596419