线程的命名和取得
由于线程的运行状态不可控,所以在程序中要取得线程,就需要给线程命名,来方便取用。关于取名,Thread类中提供有相关方法:
- 构造方法: public Thread( Runnable target, String name);
- 设置名字: public final void setName( String name);。
- 取得名字: public final String getName();。
class MyThread implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());//先获得当前线程,再获得线程名称
}
}
public class ThreadDemo {
public static void main(String[] args) throws Exception {
MyThread mt = new MyThread() ;
new Thread(mt, "线程A").start() ; // 设置了线程的名字(“线程A”)
new Thread(mt).start() ; //未设置线程名字
new Thread(mt, "线程B").start() ; // 设置了线程的名字(线程B)
}
}
- 一个Java程序的main()方法其实就是一个名字为main的主线程
- 所以主线程可以创建若干子线程
- 分出主线程和子线程的目的在于,可以将一些耗时的操作放在子线程中,从而使耗时操作不再影响整个主线程的时间(主线程负责整体流程)
线程休眠
为了使一些线程暂缓执行,就可以使用休眠处理,在Thread中有相关方法:
- 休眠: public static void sleep(long millis) throws InteruptedException;。
- 休眠: public static void sleep(long millis, int nanos) throws InterruptedException;.
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Runnable run = () -> {//Lambda表达式
for(int x=0;x<10;x++){
System.out.println(Thread. current Thread().getName()+"第"+ x+"次操作");
try {
Thread.sleep(1000); //暂缓执行,休眠操作(休眠一秒后唤起)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for(int num=0;num<5;num++){//产生五个线程
new Thread(run, "第"+num+"个线程对象") .start();
}
}
}
上面程序中的五个线程操作的休眠和唤起并不是一起的,是有先后的
线程中断
休眠里面提供有一个中断异常,所以休眠是可以被打断的,在Thread类中提供有打断线程的方法:
- 判断线程是否被中断: public boolean isInterrupted();
- 中断线程执行: public void interrupt();
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(()->{
System.out.println("72个小时的疯狂我需要睡觉补充精力") ;
try {
Thread.sleep(10000) // 预计准备休眠10秒.
System.out.println("睡足了,可以出去继续祸害别人了");
} catch (InterruptedException e) {
System.out.println("突然被别人打醒了,心情郁闷")
}
}) ;
thread.start();//开始睡
Thread.sleep(5000);//五秒钟后
if (!thread.isInterrupted()) {//该线程中断了吗?(睡着了吗)
System.out.println("睡觉是不可能让你睡觉的,起来嗨")
thread.interrupt(); // 中断执行(如果睡着了,就会被别人打醒)
}
}
}
所有正在执行的线程都是可以被打断的,中断线程必须进行异常的处理
线程强制运行
为了让某一个线程对象可以一直独占资源,直到该线程的结束,就可以让该线程强制执行。thread类提供有一下方法:
- 强制执行: public final void join() throws InterruptedException;
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread mainThread = Thread.currentThread() ; //获得当前线程(主线程)
Thread thread = new Thread(() -> {
for(int x=0;x<100;x++){//首先由两个线程抢占资源
if(x==3){//如果普通窗口已经卖了三张票,那么剩下的票由VIP窗口先卖
try{
mianThread.join();//强制让VIP先卖票(强制执行)
}catch(InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);//一秒钟抢一次
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.current Thread().getName()+"卖票"+ x);
}
},"【普通窗口】") ;
thread.start();
for (int x=0;x<100 ; x ++) {
Thread.sleep(1000);//一秒钟抢一次
System.out.print1n(" 【VIP窗口的票】=" + x);
}
}
}
在进行线程强制执行的时候一定要获取强制执行线程对象之后才可以执行join的调用
线程礼让
先将资源让出给其他线程先执行,Thread类提供有方法:
- 礼让: public static void yield()
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread mainThread = Thread.currentThread() ; //获得当前线程(主线程)
Thread thread = new Thread(() -> {
for(int x=0;x<100;x++){//首先由两个线程抢占资源
if (x%3==0) {//每卖三张票就先让VIP卖一张
Thread.yieLd(); // 线程礼让
System.out.println("###普通窗口礼让执行###");
}
try {
Thread.sleep(1000);//一秒钟抢一次
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.current Thread().getName()+"卖票"+ x);
}
},"【普通窗口】") ;
thread.start();
for (int x=0;x<100 ; x ++) {
Thread.sleep(1000);//一秒钟抢一次
System.out.print1n(" 【VIP窗口的票】=" + x);
}
}
}
线程优先级
理论上来说优先级越高越有可能先执行,Thread类中提供有方法:
- 设置优先级: public final void setPriority(int newPriority)
- 获取优先级: public final int getPriority()
设置优先级的时候是由int控制的,所以int有三个优先级:
- 最高优先级: public static final int MAX_PRIORITY、 10; .
- 中等优先级: public static final int NORM_PRIORITY、5;。
- 最低优先级: public static final int MIN_PRIORITY、 1;
public class ThreadDemo {
public static void main(String[ ] args) throws Exception {
Runnable run = ()->{
for (int x=0;x<10;x++){
try {
Thread . sleep( 1000);
} catch ( InterruptedException e) {
e. printStackTrace( );
}
System out println(Thread current Thread(). getName() + "执行。");
}
};
Thread threadA = new Thread(run, "线程对象A") ;
Thread threadB = new Thread(run, "线程对象B") ;
Thread threadC = new Thread(run, "线程对象C" ) ;
threadA. setPriority(Thread .MIN_ PRIORITY);//设置优先级
threadB setPriority(Thread .MIN_ PRIORITY);
threadc setPriority(Thread .MAX_ PRIORITY);
threadA. start();
threadB. start( );
threadC. start( );
}
}
主线程属于中等优先级,默认的线程也是中等优先级,所以是并发执行的