线程的命名和取得
多线程的运行状态是不确定的,那么在程序开发之中为了获取到一些需要使用的进程就只能依靠线程和名字来进行操作。所以线程名字是一个至关重要的概念,这样在Thread类中就提供有线程名称的处理:
//构造方法
public Thread(Runnable target,String name)
//设置名字
public final void setName(String name)
//取得名字
public final String getName()
对于线程对象的获得不可能只依靠一个this来完成的,因为线程的状态不可控,但是有一点是明确的,所有线程对象一定要执行run方法,那么这个时候可以考虑获取当前线程,在Thread类里面提供有获取当前线程的一个方法:
public static Thread currentThread()
观察线程的命名操作:
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class ThreadMethod {
public static void main(String[] args) {
MyThread mt = new MyThread();
new Thread(mt,"线程A").start();//设置了线程的名字
new Thread(mt).start();//未设置线程的名字
new Thread(mt,"线程B").start();//设置了线程的名字
}
}
/**运行结果:
线程A
Thread-0
线程B**/
当开发者为线程设置名字的时候就使用设置的名字,没有设置则会自动生成一个不重复的名字,这种自动的属性命名主要是依靠了static属性完成的,在Thread类中定义了如下操作:
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
观察程序:
MyThread mt = new MyThread();
// new Thread(mt,"线程A").start();
mt.run();
//执行结果run
在主方法中调用线程对象的run()方法所获得的线程对象的名字为"main"。所以可以得出一个结论,主方法也是一个线程。
所有线程都是进程上的划分,那么进程在哪里?
每当使用java命令执行程序的时候表示启动了一个JVM进程,一台电脑上可以同时运行多个JVM进程,每一个JVM进程都有各自的线程。在任何的开发之中主线程可以创建若干个子线程,创建子线程的目的是可以将一些复杂的逻辑或者比较耗时的逻辑交给子线程处理。
范例 子线程的处理:
public static void main(String[] args) {
System.out.println("执行任务一");
new Thread(()->{
int temp=0;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
temp+=i;
}
}).start();
System.out.println("执行任务二");
}
主线程负责处理整体流程,而子线程负责处理耗时流程。
线程休眠
如果希望一个线程可以暂缓处理,那么可以使用休眠的处理。
在Thread类中定义的休眠方法如下:
//休眠一
public static void sleep(long millis) throws InteruptedException
//休眠二
public static void sleep(long millis,int nanos) throws InteruptedException //多了纳秒
在进行休眠的时候可能会产生InteruptedException异常,中断异常属于Exception的子类,所以该异常必须进行处理。
观察休眠处理:
public static void main(String[] args) {
new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"线程对象").start();
}
暂缓执行之后执行变慢了,休眠时间一到马上恢复继续执行。休眠的主要特点是可以自动实现线程的唤醒,以继续进行后续的处理。但需要注意的是,如果现在你有多个线程对象,那么休眠也是有向后顺序的。
范例:产生多个线程对象进行休眠处理
public static void main(String[] args) {
for (int num = 0; num < 5; num++) {
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "线程对象"+num).start();
}
}
此时将产生五个线程对象,并且这五个线程对象执行的方法体是相同的,此时从程序执行的感觉来讲,就像是若干个线程一起进行了休眠然后一起进行了自动唤醒,实际上是有区别的,
线程中断
在之前发现线程的休眠里面提供有一个中断异常,说明线程的休眠是可以被打断的,而这种打断肯定是由其他线程完成的,Thread类中提供有中断执行的处理方法:
//判断线程是否被中断
public boolean is Interrupted()
//中断线程执行
public void interupt()
观察中断操作:
public class ThreadInterupt {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
System.out.println("睡觉补充精力");
try {
Thread.sleep(10000);//预计休眠10s
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("睡足了");
});
thread.start();//开始睡
Thread.sleep(1000);
if(!thread.isInterrupted()){
thread.interrupt();//中断执行
}
}
}
所有正在执行的线程都是可以被中断的,中断线程必须进行异常的处理
线程强制运行
线程强制执行指的是当满足某些条件之后,某一个线程对象 可以一直独占资源一直到该线程的程序执行结束。
以上一个程序为例,主线程和子线程交叉执行,如果想要主线程独占执行,可以利用Thread类中的方法强制执行。
public final void join() throws InteruptedException
public class ThreadInterupt {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
System.out.println("睡觉补充精力");
try {
Thread.sleep(10000);//预计休眠10s
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("睡足了");
});
thread.start();//开始睡
Thread.sleep(1000);
if(!thread.isInterrupted()){
thread.interrupt();//中断执行
}
}
}
在进行线程强制执行的时候 一定要获取强制执行对象之后才可以执行join()方法。
线程礼让
线程礼让指的是将资源让出去,让别的线程先执行。线程的礼让可以使用Thread类中提供的方法:
public static void yield()
礼让执行的时候每一次调用yield()方法都只会礼让一次当前的资源。
线程优先级
从理论上讲,线程的优先级越高越有可能先执行(也越有可能抢占到资源)
在Thread类中对于优先级的操作提供有如下两个方法:
//设置优先级
public final void setPriority(int newPriority)
//获取优先级
public final int getPriority()
在进行优先级定义的时候都是通过int型来完成的,而对于此数字的选择在Thread类中就定义有三个常量:
//最高优先级
public static final int MAX_PRIORITY
//中等优先级
public static final int NORM_PRIORITY
//最低优先级
public static final int MIN_PRIORITY
public static void main(String[] args) throws Exception {
Runnable runnable=()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
}
};
Thread threadA = new Thread(runnable, "线程A");
Thread threadB = new Thread(runnable, "线程B");
Thread threadC = new Thread(runnable, "线程C");
threadA.setPriority(Thread.MAX_PRIORITY);
threadB.setPriority(Thread.NORM_PRIORITY);
threadC.setPriority(Thread.MIN_PRIORITY);
threadA.start();
threadB.start();
threadC.start();
System.out.println( Thread.currentThread().getPriority());
}
主线程属于中等优先级,而默认创建的线程也是中等优先级,优先级高的可能先执行而不是绝对执行。