Java多线程之线程控制
文章目录
1.线程对象的名称
1.1获取线程对象的名称
public final String getName():获取线程对象的名称。
public class MyThread extends Thread {
public MyThread(){
}
public MyThread(String name){
super(name);//调用父类的构造方法
}
@Override
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println(i +"---"+ getName());//获取到线程对象的名称
}
}
}
1.2设置线程对象的名称
public final void setName():设置线程对象的名称。
public class MainDemo {
public static void main(String[] args) {
//获取线程对象
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
//给线程设置名称
my1.setName("aaa");
my2.setName("bbb");
//启动线程,由jvm执行run方法
my1.start();
my2.start();
//获取main方法所在线程对象的名称
//public static Thread currentThread():返回当前正在执行的线程对象。
System.out.println(Thread.currentThread().getName());
}
}
1.3针对非Thread类的子类获取线程对象名称
public static Thread currentThread():返回当前正在执行的线程对象。
Thread.currentThread.getName():得到当前线程对象的名称。
2.线程调度
假如计算机只有一个CPU(单核),那么CPU在某一个时刻只能执行一条指令,线程只得到CPU时间片,也就是使用权,(也称为执行权)才可以执行指令。线程的调度模型一般有两种:
- 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片。
- 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU的时间片相对多一些。
java使用的是抢占式调度模型。
3.获取线程的优先级
public final int getPriority():返回线程的优先级。
4.设置线程的优先级
public final void setPriority(int newPriority):更改线程的优先级
注意:线程默认的优先级为5,线程优先级的范围:1-10
MyThreadPriority tp = new MyThreadPriority();
tp.setName("a");//设置线程对象名称
System.out.println(tp.getPriority());//获取线程对象的优先级
tp.setPriority(10);//设置线程对象的优先级
tp.start();//启动线程
5.线程控制
5.1线程休眠
public static void sleep(long millis):写在自定义的线程代码中,线程执行到这里时,休眠指定时间,单位为毫秒。
public class ThreadSleep extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+":"+i +",日期:"+new Date());
try {
Thread.sleep(1000);//线程休眠一秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
5.2线程加入(抢占)
public final void join();
public class MainDemo {
public static void main(String[] args) {
ThreadJoin t1 = new ThreadJoin();
ThreadJoin t2 = new ThreadJoin();
ThreadJoin t3 = new ThreadJoin();
t1.start();
try { //让t1线程先走完,其他线程才能继续运行。
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
t3.start();
}
}
5.3线程礼让
public static void yield():暂停当前正在执行的线程对象,并执行其他线程。
public class ThreadYield extends Thread {
@Override
public void run() {
for (int i = 0; i <100; i++) {
System.out.println(getName()+":"+i);
Thread.yield();//暂停当前正在执行的线程对象,并执行其他线程。
}
}
}
5.4后台线程(守护线程)
public final void setDaemon(boolean on):将该线程标记为守护线程。
当正在运行的线程都是守护线程时,java虚拟机退出。该方法必须在启动线程前调用。
public class MainDemo {
public static void main(String[] args) {
ThreadDaemon t1 = new ThreadDaemon();
ThreadDaemon t2 = new ThreadDaemon();
t1.setName("a");
t2.setName("b");
t1.setDaemon(true);//设置a线程为守护线程
t2.setDaemon(true);//设置b线程为守护线程
t1.start();
t2.start();
Thread.currentThread().setName("c");//获取当前线程,并设置名称为c
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}//效果:当c线程执行完毕之后,a、b无论执行到哪里,都会停止掉(因为缓存的原因,a、b可能会向下多执行一点)。
5.5中断线程
public final void stop():让线程停止,过时了,但是现在任然可以使用。不建议使用。
public void interrupt():中断线程。把线程状态终止,并抛出一个InterruptedException.
//自定义线程
public class ThreadStop extends Thread {
@Override
public void run() {
System.out.println("开始执行:"+new Date());
/*for (int i = 0; i < 100; i++) {
System.out.println(getName()+":" + i);
}*/
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
/*e.printStackTrace();*/
System.out.println("线程终止了");
}
System.out.println("结束执行"+new Date());
}
}
//maindemo
public class MainDemo {
public static void main(String[] args) {
ThreadStop t = new ThreadStop();
t.setName("a");
t.start();
try { //超过三秒线程没醒过来,就终止线程。
Thread.sleep(3000);
//t.stop();//输出结果:开始执行:Fri Oct 20 20:23:09 CST 2017
t.interrupt(); //输出结果:开始执行:Fri Oct 20 20:23:40 CST 2017
//线程终止了
//结束执行Fri Oct 20 20:23:43 CST 2017
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}