zoukankan      html  css  js  c++  java
  • 线程中断、线程让步、线程睡眠、线程合并

    线程中断

    线程中断涉及到三个方法,如下:

    interrupt()方法用于中断线程,通常的理解来看,只要某个线程启动后,调用了该方法,则该线程不能继续执行了,来看个小例子:

    运行后,我们发现,线程t一直在执行,没有被中断。

    其实interrupt()方法并不是中断线程的执行,而是为调用该方法的线程对象打上一个标记,设置其中断状态为true,通过isInterrupted()方法可以得到这个线程状态,我们将上面的程序做一个小改动:

    class MyThread extends Thread{
    	int i=0;
    	public MyThread(String name) {
    		super(name);
    	}
    	public void run() {
    		while(!isInterrupted()){//当前线程没有被中断则执行
    			System.out.println(getName()+":"+getId()+":执行了"+ ++i+"次");			
    		}
    	}
    }
    public class TestInterrupt {
    public static void main(String[] args) throws InterruptedException {
    	MyThread t=new MyThread("MyThread");
    	t.start();
    	Thread.sleep(100);//睡眠100毫秒
    	t.interrupt();//中断t线程
    }
    }
    

      这样的话,线程被顺利的中断执行了。很多人实现一个线程类时,都会再加一个flag标记,以便控制线程停止执行,其实完全没必要,通过线程自身的中断状态,就可以完美实现该功能。如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个InterruptedException。 我们可以捕获该异常,并且做一些处理。另外,Thread.interrupted()方法是一个静态方法,它是判断当前线程的中断状态,需要注意的是,线程的中断状态会由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。

    线程让步

    线程让步,其方法如下:

    线程让步用于正在执行的线程,在某些情况下让出CPU资源,让给其它线程执行,来看一个小例子:

    class MyThread extends Thread{
    	int i=0;
    	public MyThread(String name) {
    		super(name);
    	}
    	public void run() {
    		while(!isInterrupted()){//当前线程没有被中断则执行
    			System.out.println(getName()+":"+getId()+":执行了"+ ++i+"次");			
    			if(i%10==0){//当i能对10整除时,则让步
    				Thread.yield();
    			}
    		}
    	}
    }
    public class TestInterrupt {
    public static void main(String[] args) throws InterruptedException {
    	//创建线程对象
    	MyThread t1=new MyThread("MyThread1");
    	MyThread t2=new MyThread("MyThread2");
    	//启动线程
    	t1.start();
    	t2.start();
    	Thread.sleep(100);//主线程睡眠100毫秒
    	//终止线程
    	t1.interrupt();
    	t2.interrupt();
    }
    }
    

      从输出结果可以看到,当某个线程(t1或者t2)执行到10次、20次、30次等时,就会马上切换到另一个线程执行,接下来再交替执行,如此往复。注意,如果存在synchronized线程同步的话,线程让步不会释放锁(监视器对象)。

    线程睡眠

    线程睡眠涉及到两个方法,如下:

    线程睡眠的过程中,如果是在synchronized线程同步内,是持有锁(监视器对象)的,也就是说,线程是关门睡觉的,别的线程进不来,来看一个小例子:

    class Service{
    	public synchronized void calc(){
    		System.out.println(Thread.currentThread().getName()+"准备计算");
    		System.out.println(Thread.currentThread().getName()+"累了睡觉");
    		try {
    			Thread.sleep(10000);//睡眠10秒
    		} catch (InterruptedException e) {
    			return;
    		}
    		System.out.println(Thread.currentThread().getName()+"醒了准备计算");
    		System.out.println(Thread.currentThread().getName()+"计算完成");
    	}
    }
    class MyThread extends Thread{
    	private Service service;
    	public MyThread(String name,Service service) {
    		super(name);
    		this.service=service;
    		
    	}
    	public void run() {
    	 service.calc();
    	}
    }
    public class TestInterrupt {
    public static void main(String[] args) throws InterruptedException {
    	//创建共享对象
    	Service service=new Service();
    	//创建线程对象
    	MyThread t1=new MyThread("MyThread1",service);
    	MyThread t2=new MyThread("MyThread2",service);
    	//启动线程
    	t1.start();
    	t2.start();
    }
    }
    

      输出结果:

    MyThread2准备计算
    MyThread2累了睡觉
    MyThread2醒了准备计算
    MyThread2计算完成
    MyThread1准备计算
    MyThread1累了睡觉
    MyThread1醒了准备计算
    MyThread1计算完成

    线程合并

    线程合并涉及到三个方法,如下:

    线程合并是优先执行调用该方法的线程,再执行当前线程,来看一个小例子:

    class MyThread extends Thread{
    	public MyThread(String name) {
    		super(name);	
    	}
    	public void run() {
    	for(int i=0;i<=10;i++){
    		System.out.println(getName()+":"+getId()+"执行了"+i+"次。");
    	}
    	}
    }
    public class TestInterrupt {
    public static void main(String[] args) throws InterruptedException {
    	//创建线程对象
    	MyThread t1=new MyThread("MyThread1");
    	MyThread t2=new MyThread("MyThread2");
    	//启动线程
    	t1.start();
    	t2.start();
    	//线程合并
    	t1.join();
    	t2.join();
    	System.out.println("主线程开始执行!");
    }
    }
    

      t1和t2都执行完才继续主线程的执行,所谓合并,就是等待其它线程执行完,再执行当前线程,执行起来的效果就好像把其它线程合并到当前线程执行一样。

    线程优先级

    线程最低优先级为1,最高优先级为10,看起来就有10个级别,但这10个级别能不能和CPU对应上,还未可知,Thread类中提供了优先级的三个常量,如下:

    我们创建线程对象后,如果不显示的设置优先级的话,默认为5。优先级可以看成一种特权,优先级高的,获取CPU调度的机会就大,优先级低的,获取CPU调度的机会就小,这个和我们现实生活很一样啊,优胜劣汰。线程优先级的示例就不写了,比较简单。

    wait()和sleep()区别:

    他们最大本质的区别是:sleep()不释放同步锁,wait()释放同步

  • 相关阅读:
    【leetcode】1365. How Many Numbers Are Smaller Than the Current Number
    【leetcode】1363. Largest Multiple of Three
    【leetcode】1362. Closest Divisors
    【leetcode】1361. Validate Binary Tree Nodes
    【leetcode】1360. Number of Days Between Two Dates
    【leetcode】1359. Count All Valid Pickup and Delivery Options
    【leetcode】1357. Apply Discount Every n Orders
    【leetcode】1356. Sort Integers by The Number of 1 Bits
    ISE应用入门的一些问题
    DDR的型号问题
  • 原文地址:https://www.cnblogs.com/ipetergo/p/6816928.html
Copyright © 2011-2022 走看看