线程 之 线程控制

下面有几种方法可以很好的控制线程的执行。
1.join 线程控制
2.后台线程(守护线程)
3.sleep线程睡眠
4.yield线程让步

1.join 线程控制。
Thread提供了让一个线程等待另外一个线程完成的方法-------join()方法
意思:当在a程序执行流(线程)中调用b线程的jion()方法,调用者(a)就会被阻塞(出于冻结状态),直到jion()
线程(b)被执行完为止。
jion() 方法经常被使用线程的程序调用,以将大问题划分为很多小问题,每个小问题分配一个线程,当所有的小问题得到处理后,在调用主线程来进一步操作。
package myclass;

public class JoinThread extends Thread
{
//提供一个有参数的构造函数,用来设置新线程的名字
JoinThread(String name)
{
super(name);
}
//重写run()方法,定义线程执行体
public void run()
{
for(int x=0;x<100;x++)
{
System.out.println(getName() + " " + x);
}
}

public static void main(String[] args)throws Exception //一定要抛出异常或者Try join(),方法。
{
//启动一个线程
JoinThread st1 = new JoinThread(“新线程”);
st1.start();

    for(int x=0;x<100;x++)
    {
         if(x == 20)
         {
               //创建第二个线程
              JoinThread st2 = new JoinThread(“被join的线程”);
              st2.start();
              //main 线程调用了st2线程的join()方法,
              //main 线程必须等待st2执行结束才会向下执行。
              st2.join();
          }
          System.out.println(Thread.currentThread() + "   " + x);
     }
}

}
这个程序一共启动了三个线程,分别为 st2线程、st1线程、主线程。
刚开始,三个线程快速切换执行,等到主线程执行到x=20时候,主线程进入阻塞(冻结)状态,st1线程和st2线程进行快速切换执行。直到st2线程执行完毕,主线程才会执行。
2.后台线程
这种线程在后台运行,主要任务是为其他线程提供服务,这种线程就是守护线程(Daemon Thread).JVM就是最经典的守护线程(后台线程)。
后台线程的特征就是:所有线程都死亡时候,后台线程就会自动死亡。
通过setDaemon(true) 方法将线程设置成为后台线程。
当整个程序只剩下后台线程时,虚拟机也会退出,
package myclass;

public class DaemonThread extends Thread
{
//重写run()方法
public void run()
{
for(int x=0;x<100;x++)
{
System.out.println(getName() + " " + x);
}
}

 public static void main(String[] args)
 {
 //将t线程设置成为了守护线程。
      DaemonThread t= new DaemonThread();
      t.setDaemon(true);
      t.start();
      for(int x = 0;x <100;x++)
      {
          System.out.println(Thread.currentThread().getName() + "    " + x);
       }
  }

}

在上面的程序中,本来主线程和t线程都会执行到100,但是将t线程设置成为守护线程以后,主线程是里面的唯一一个前台线程,当主线程结束后,守护线程也会自动死亡,虚拟机退出。(守护线程和其他线程一样)

注意:守护线程应该在start()方法之前设置。

3.线程睡眠
如果想让当前正在执行的线程暂停 一段时间,进入阻塞状态,则调用Thread类中的静态方法sleep()来说实现。
当前线程调用sleep()方法后,会进入阻塞状态,不会或得执行权,因此用sleep()来暂停程序的执行。
package myclass;
public class SleepTest extends Thread//不需要继承Thread类
{
public static void main(String[] args)throws Exception //需要抛出异常
{
for(int x=0;x<100;x++)
{
//System.out.println("当前时间为: " + new Date());
//调用sleep()方法让线程暂停1s
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " " +x);
}
}
}

4.静态方法yield ()
它也可以让正在执行的线程暂停,但是不是进入阻塞状态,而是进入就绪状态(等待cpu赋给执行权)
当调用yield()执行后,只有优先级和当前优先级相同或者高于当前优先级的出于就绪状态的线程会被调度出来执行。

扫描二维码关注公众号,回复: 3953046 查看本文章

package myclass;

public class YieldTest extends Thread
{
YieldTest(String name)
{
super(name);
}
public void run()
{
for(int x=0;x<100;x++)
{
System.out.println(getName()+ " " + x);
if(x == 20)
Thread.yield();
}
}
public static void main(String[] args)
{
//设置主线程的优先级
Thread.currentThread().setPriority(6);
YieldTest y1 = new YieldTest(“高级”);
//设置该线程的优先级
y1.setPriority(Thread.MAX_PRIORITY);
y1.start();
YieldTest y2 = new YieldTest(“低级”);
y2.setPriority(Thread.MIN_PRIORITY);
y2.start();
}
}

5.线程的优先级:每个线程执行都有一定的优先级,优先级高的获取更多的执行权。

在默认的情况下,一般都是5 NORM_PRIORITY
最低位1 MIN_PRIORITY
最高位10 MAX_PRIORITY
Thread类通过setPriority(int newPriority)、getPriority()来设置和返回指定线程的优先级。

猜你喜欢

转载自blog.csdn.net/weixin_43247990/article/details/83450744
今日推荐