线程大家都会创建,这里介绍一些常用的方法。
休眠(sleep):
就和睡觉一样,假设工作是一个任务,你需要休息,因此你可以什么都不做,休息你指定的时间,接着工作。
public class MyWork implements Runnable {
static int num = 24;
@Override
public void run() {
while(num > 0){
System.out.println("在工作..");
num --;
// 工作累了 休息
try {
// 线程内置方法, 默认是以毫秒为单位
Thread.sleep(1000);
// 这是对时间颗粒度更加精确的一个类,只是处理了时间,实际还 // 是会调用Thread.sleep,
// 具体请看源码 和 API
//TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(1);
ex.execute(new MyWork());
ex.shutdown();
}
}
Thread.yield():
这是native 方法,当有多个线程的时候,A线程 调用了这个方法,会立即放弃当前线程,让另外的B线程先执行。
Thread.interrupted():
线程打断,就是当你在睡觉途中,也可以将你喊醒。这会出现异常,唤醒之后继续执行。
public static void main(String[] args) {
MyWork m = new MyWork();
Thread t = new Thread(m);
t.start();
t.interrupt();
}
wait():线程等待,也是让你去休息。可以加入时间。可以通过notify() 唤醒。
区别:sleep 会占用CPU,不让别人用。相当于你在办公室睡觉,办公室就不能让别人用的,醒了之后依然是你用着的。wait 不会占CPU,让你到睡觉区域(线程池)。办公室就空闲出来。如果时间到了,或者被唤醒,你们又要从新争夺谁 先使用办公室,这是线程调度控制。
有些时间,我们需要让线程优先执行,理论上我们最好不要干预调度器,因为时间片很短,无法察觉,但是还是可以干扰的。
public static void main(String[] args) {
// 工作线程
MyWork m = new MyWork();
// 玩的线程
Play a = new Play();
Thread t = new Thread(m);
Thread t1 = new Thread(a);
t1.start();
t1.setPriority(10);
t.start();
t.setPriority(2);
}
setPriority :设置线程优先级别,JAVA 默认是5,有1-10个级别。超出了就异常了。这里的优先级不是绝对的。比如 优先级 1 跟 2 之间 ,2的优先级虽然大于1,只能保证大多数2的线程先执行,并不是全部。如果像t1 线程设置成10.优先级就比2 高太多。很大程度上能保证t1 全部执行。影响只是相对的。
后台进程(daemon):也叫守护线程。是指程序运行的时候后台提供的一种通用服务的线程,这种线程不属于程序中不可缺少的部分。当非后台线程结束时,程序结束,并且杀死后台进程。相当于一个主从关系,主要的结束了,其他的就结束了。main 就是非后台进程。
(守护线程作用)setDaemon: 是true,才设置成守护线程,这个很好理解,也是一个线程,不过有个依赖关系。举个例子:比如我工作累,在休息。但是又怕睡久了,老板找我麻烦。因此我可以让我父母再我睡了30分钟后,通知我起床。 我相当于 主线程,父母就是守护线程。如果我已经被叫醒了,或者我自动醒了, 那么他们 就不用再叫我,也就结束了。下面看代码:
public class ParentDaemon implements Runnable {
static int num = 10;
@Override
public void run() {
while(num > 0){
if(num != 1){
System.out.println("等待中..."+num);
}else{
System.out.println("小强,快起床了...");
}
num --;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ParentDaemon p = new ParentDaemon();
Thread t = new Thread(p);
t.setDaemon(true);
t.start();
try {
// 主线程main() (我) 在休息。
// 这里可以将时间 延迟到 10000,设置我自动醒,和被叫醒两种模式。
// 如果是10,我自动醒,那么 守护线程就结束了,否者一直执行。
t.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
isDaemon : 判断当前线程是否是守护线程。
Thread.join:表示A 线程调用了此方法,A 就会先执行 完毕。当然 也可以interrupt 打断。
public class Play implements Runnable {
static int num = 24;
@Override
public void run() {
while(num > 0){
System.out.println("在玩..");
num --;
}
}
public static void main(String[] args) {
Play pl = new Play();
Thread t = new Thread(pl);
t.start();
// 可以尝试不用 join ,看看效果
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("这是主线程,由于用了join 方法,因此t 线程比我(main )先执行完毕");
}
}
join 其实使用了synchronized 同步,等待该线程终止,里面可以使用参数,即等待该线程的时间。