文章目录
- Thread中常用的方法
- 栗子1:setName()
- 栗子2:getId()
- 栗子3:currentThread()
- 栗子4:sleep(long timeMillis)
Thread中常用的方法
-
void run()
//不推荐使用 -
void start()
//开启线程,该方法会开启新的线程,并调用void run()
方法 -
void setName(String name)
//设置线程的名称,通常用于调试 -
String getName()
//获取线程的名称 -
long getId()
//获取线程 id,该 id 是由系统分配的,每个线程的 id 是唯一的
栗子1:setName()
CustomThread
class CustomThread extends Thread {
public CustomThread() {
setName("自定义线程类");
}
public void run() {
super.run();
for (int i = 0; i < 10; i++) {
System.out.println(getName() + i);
}
}
}
Main
public class Main {
public static void main(String[] args) {
System.out.println("主线程开始-----------------");
CustomThread thread = new CustomThread();
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println("Main i=" + i);
}
System.out.println("主线程结束");
}
}
运行结果
主线程开始-----------------
Main i=0
......
Main i=9
主线程结束
自定义线程类0
......
自定义线程类9
栗子2:getId()
name 可以重复,id 是不会重复的
代码改为
CustomThread
System.out.println(getName() + "(" + getId() + ")" + i);
运行结果:
主线程开始-----------------
Main i=0
......
Main i=9
主线程结束
自定义线程类(13)0
......
自定义线程类(13)9
栗子3:currentThread()
刚才的一些操作都是在自定义的线程类中操作的,如果想在在主线程中获取 id,或者在 Runnable 接口中获取id,就需要依靠以下方法
-
static Thread currentThread()
//获取当前线程的对象
Main
System.out.println("主线程开始");
CustomThread thread = new CustomThread();
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println("Main(" + Thread.currentThread().getId() + ") i=" + i);
}
System.out.println("主线程结束");
输出结果(主线程的id是1)
主线程开始
Main(1) i=0
......
Main(1) i=8
Main(1) i=9
主线程结束
自定义线程类(13)0
自定义线程类(13)1
......
自定义线程类(13)7
自定义线程类(13)8
自定义线程类(13)9
Process finished with exit code 0
同样的 CustomRunner 可以改为
CustomRunner
class CustomRunner implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("CustomRunner(" + Thread.currentThread().getId() + ")i=" + i);
}
}
}
栗子4:sleep(long timeMillis)
-
void sleep(long timeMillis)
//休眠,使得线程在接下来的 timeMillis 时间不工作
Main 代码修改为
long start = System.currentTimeMillis();
for (int i = 0; i < 60; i++) {
System.out.println(new Date());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
运行结果是:程序每秒执行一次,输出当前时间
再写一个关于 sleep 的栗子
Main 代码改为
System.out.println("主线程开始");
//子线程1
CustomThread ct = new CustomThread();
ct.start();
//子线程2
CustomRunner cr = new CustomRunner();
Thread t = new Thread(cr);
t.start();
try {
t.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//主线程
for (int i = 0; i < 100; i++) {
System.out.println("Main i=" + i);
}
System.out.println("主线程结束");
运行程序:
主线程开始
CustomRunner(14)i=0
CustomRunner(14)i=1
......
CustomRunner(14)i=9
自定义线程类(13)0
......
自定义线程类(13)9
Main i=0
Main i=1
......
Main i=99
主线程结束
子线程1和子线程2交替执行,5秒钟后,主线程执行
其实代码中的 t.sleep(5000);
可以写成 ct.sleep(5000);
或者 Thread.sleep(5000);
sleep 这句代码出现在哪个线程中,表示的就是哪个线程 sleep,刚才的代码中,sleep 出现在 main() 中,所以主线程休眠 5s 执行了。
如果想让子 线程2 休眠,应该在 CustomRunner 中加
class CustomRunner implements Runnable {
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("CustomRunner(" + Thread.currentThread().getId() + ")i=" + i);
}
}
}
执行结果:子线程 1 和主线程交替执行,5秒后,子线程 2 执行
最后说一个细节
反复创建对象,很耗费内存,在刚才栗子4中的代码中,for 循环中创建了60个 Date 对象,可以优化为
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = new Date();
for (int i = 0; i < 60; i++) {
d.setTime(System.currentTimeMillis());
System.out.println(sdf.format(d));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
或者
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = new Date();
long timeMillis = d.getTime();
for (int i = 0; i < 60; i++) {
d.setTime(timeMillis);
System.out.println(sdf.format(d));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
timeMillis += 1000;
}
}