可以通过Thread的构造方法或者setName方法给线程命名。
Thread th = new Thread(new MyRunnable(),"线程名字");
Thread th = new Thread(new MyRunnable());
th.setName("线程名字");
使用Thread.currentThread().getName()获得当前线程的名字。
例如:在主方法中启动一个线程计算1+2+3+…+100的求和。程序的入口方法main方法是主线程(main线程),计算求和是另一个子线程,所以程序运行时是两个线程同时执行。
代码如下:
class MyRunnable implements Runnable{
@Override
public void run() {
long result=0;
for(int i=1;i<=100;i++){
result += i;
System.out.println(Thread.currentThread().getName() + ",i=" + i);//获取当前线程的名字
try {
Thread.sleep(50); //当前线程休眠50毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("result=" + result);
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread th = new Thread(new MyRunnable());
th.setName("我的线程1");//给线程命名
th.start();//启动线程
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+",i=" + i);
Thread.sleep(200);
}
}
}
运行结果:
main,i=0
我的线程1,i=1
我的线程1,i=2
我的线程1,i=3
我的线程1,i=4
main,i=1
我的线程1,i=5
我的线程1,i=6
我的线程1,i=7
我的线程1,i=8
main,i=2
我的线程1,i=9
我的线程1,i=10
我的线程1,i=11
我的线程1,i=12
main,i=3
我的线程1,i=13
我的线程1,i=14
我的线程1,i=15
我的线程1,i=16
main,i=4
我的线程1,i=17
我的线程1,i=18
我的线程1,i=19
我的线程1,i=20
main,i=5
我的线程1,i=21
我的线程1,i=22
我的线程1,i=23
我的线程1,i=24
main,i=6
我的线程1,i=25
我的线程1,i=26
我的线程1,i=27
我的线程1,i=28
main,i=7
我的线程1,i=29
我的线程1,i=30
我的线程1,i=31
我的线程1,i=32
main,i=8
我的线程1,i=33
我的线程1,i=34
我的线程1,i=35
我的线程1,i=36
main,i=9
我的线程1,i=37
我的线程1,i=38
我的线程1,i=39
我的线程1,i=40
我的线程1,i=41
我的线程1,i=42
我的线程1,i=43
我的线程1,i=44
我的线程1,i=45
我的线程1,i=46
我的线程1,i=47
我的线程1,i=48
我的线程1,i=49
我的线程1,i=50
我的线程1,i=51
我的线程1,i=52
我的线程1,i=53
我的线程1,i=54
我的线程1,i=55
我的线程1,i=56
我的线程1,i=57
我的线程1,i=58
我的线程1,i=59
我的线程1,i=60
我的线程1,i=61
我的线程1,i=62
我的线程1,i=63
我的线程1,i=64
我的线程1,i=65
我的线程1,i=66
我的线程1,i=67
我的线程1,i=68
我的线程1,i=69
我的线程1,i=70
我的线程1,i=71
我的线程1,i=72
我的线程1,i=73
我的线程1,i=74
我的线程1,i=75
我的线程1,i=76
我的线程1,i=77
我的线程1,i=78
我的线程1,i=79
我的线程1,i=80
我的线程1,i=81
我的线程1,i=82
我的线程1,i=83
我的线程1,i=84
我的线程1,i=85
我的线程1,i=86
我的线程1,i=87
我的线程1,i=88
我的线程1,i=89
我的线程1,i=90
我的线程1,i=91
我的线程1,i=92
我的线程1,i=93
我的线程1,i=94
我的线程1,i=95
我的线程1,i=96
我的线程1,i=97
我的线程1,i=98
我的线程1,i=99
我的线程1,i=100
result=5050
从执行结果可以看出是两个线程交替执行,分别是主线程main,和子线程'我的线程1'。
使用Thread.sleep(long mills);使当前线程休眠,进入阻塞状态(暂停执行),如果线程在睡眠状态被中断,将会抛出IterruptedException中断异常。 主要方法如下:
sleep(long millis) 线程睡眠 millis 毫秒 sleep(long millis, int nanos) 线程睡眠 millis 毫秒 + nanos 纳秒
注意:
1.sleep()方法是Thread类的静态方法,如果调用线程对象.sleep()方法并不是该线程就休眠,反正在哪一个线程里面执行了sleep()方法哪一个线程就休眠。
2.线程睡眠到期自动苏醒,并返回到可运行状态(就绪),并不是运行状态。
实例: 下面以一个倒计时的功能来进一步说明sleep()方法的使用。
public class Test {
public static void countDown(long mills) {
Date endDate = new Date(System.currentTimeMillis() + mills);
long endTime = endDate.getTime();
while (true) {
System.out.println(new SimpleDateFormat("hh:mm:ss").format(endDate));
//下一秒时间
endDate = new Date(endDate.getTime() - 1000);
//休眠一秒钟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (endTime - endDate.getTime() > mills) {
break;
}
}
}
public static void main(String[] args) throws InterruptedException {
Test.countDown(10000); ////倒计时10秒
}
}
运行结果:
11:57:51
11:57:50
11:57:49
11:57:48
11:57:47
11:57:46
11:57:45
11:57:44
11:57:43
11:57:42
11:57:41
当某个线程调用方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行。也就是当前线程要等待别的线程执行完毕才能继续执行。
实例: 吃中饭,妈妈开始做饭。 做饭的时候发现没有酱油了,没有辣椒了。 该妈妈有两个儿子,大儿子,小儿子。大儿子买酱油,小儿子买辣椒。妈妈在家等,等酱油和辣椒都买回来之后,开始做饭。如何用多线程来描述这个故事呢?
public class MotherDemo {
public static void main(String[] args) {
System.out.println("开始做午饭了...");
////////这个时候,发现没有酱油了,没有辣椒了。
//兵分两路,派出两个线程,一个负责买辣子,一个负责买辣椒。
Runnable bigSon = ()->{
for(int i=0;i<10;i++){
System.out.println("大儿子买酱油中...");
try {
Thread.sleep(100); // 当前线程处于休眠状态。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable smallSon = ()->{
for(int i=0;i<10;i++){
System.out.println("小儿子买辣椒中...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread bigSonTh = new Thread(bigSon,"大儿子线程");
Thread smallSonTh = new Thread(smallSon,"小儿子线程");
bigSonTh.start();
smallSonTh.start();
try{
//妈妈线程中调用了join方法,分别等待两个儿子线程结束
bigSonTh.join();
smallSonTh.join();
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println("酱油和辣椒都买回来了,继续做饭...");
System.out.println("香喷喷的午饭做好了,请享用!");
}
}
运行结果:
开始做午饭了...
小儿子买辣椒中...
大儿子买酱油中...
小儿子买辣椒中...
大儿子买酱油中...
小儿子买辣椒中...
大儿子买酱油中...
大儿子买酱油中...
小儿子买辣椒中...
小儿子买辣椒中...
大儿子买酱油中...
大儿子买酱油中...
小儿子买辣椒中...
大儿子买酱油中...
小儿子买辣椒中...
小儿子买辣椒中...
大儿子买酱油中...
小儿子买辣椒中...
大儿子买酱油中...
大儿子买酱油中...
小儿子买辣椒中...
酱油和辣椒都买回来了,继续做饭...
香喷喷的午饭做好了,请享用!
1).可以通过Thread的构造方法或者setName方法给线程命名。
2).使用Thread.sleep(long mills);使当前线程休眠,进入阻塞状态(暂停执行),如果线程在睡眠状态被中断,将会抛出IterruptedException中断异常。线程睡眠到期自动苏醒,并返回到可运行状态(就绪),并不是运行状态。
3).当某个线程调用方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行。