zoukankan      html  css  js  c++  java
  • JAVA学习课第二十八届(多线程(七))- 停止-threaded多-threaded面试题


    主密钥

    /*
     * wait 和 sleep 差别?
     * 1.wait能够指定时间也能够不指定
     * sleep必须指定时间
     * 2.在同步中,对CPU的运行权和锁的处理不同
     * wait释放运行权,释放锁    sleep释放运行权,不释放锁
     */

    //同步里具备运行资格的线程不止一个,可是能得到锁的仅仅有一个,所以能运行的也仅仅有一个


    一、停止线程的方式

    不可能让线程一直在执行。所以须要让线程停止


    1.定义循环结束标记

    一般而言,线程执行代码都是循环的,仅仅要控制了循环就能够结束任务

    2.使用interrupt(中断)

    结束线程的冻结状态。使线程回到执行状态

    PS:stop过时了,不用了

    第一种方式:(经常使用)

    class StopThread implements Runnable
    {
    	private boolean flag = true;
    	public void run()
    	{
    		while(flag)
    		{
    			System.out.println(Thread.currentThread().getName()+"---");
    		}
    	}
    	public void ChangeFlag()
    	{
    		flag = false;
    	}
    }
    public class Main
    {
    	public static void main(String[] args)
    	{
    		StopThread s = new StopThread();
    		Thread t1 = new Thread(s);
    		Thread t2 = new Thread(s);
    		t1.start(); t2.start();
    		int i = 0;
    		while(true)
    		{
    			if(++i == 20)//i达到20后结束全部线程
    			{
    				s.ChangeFlag();
    				break;
    			}
    			System.out.println("Main.main"+i);
    		}
    			System.out.println("Final");
    	}
    }

    缺点:

    class StopThread implements Runnable
    {
    	private boolean flag = true;
    	public synchronized void run()
    	{
    		while(flag)
    		{
    			try {
    				wait();
    			} catch (InterruptedException e) {
    				// TODO: handle exception
    				System.out.println(Thread.currentThread().getName()+"..."+e);
    			}
    			System.out.println(Thread.currentThread().getName()+"-++--");
    		}
    	}
    	public void ChangeFlag()
    	{
    		flag = false;
    	}
    }

    主线程结束了。t0 t1直接wait()了。假设线程处于了冻结状态。就无法读取标记,所以就引入了另外一种结束线程的方式


    另外一种方式:interrupt

    将线程从冻结状态强制恢复到执行状态中。使线程回到具备CPU执行资格的状态。可是会发生中断异常(InterruptException)

    class StopThread implements Runnable
    {
    	private boolean flag = true;
    	public synchronized void run()
    	{
    		while(flag)
    		{
    			try {
    				wait();
    			} catch (InterruptedException e) {
    				// TODO: handle exception
    				System.out.println(Thread.currentThread().getName()+"........."+e);
    				flag = false;//注意处理,不加这个会导致线程继续等待。主线程结束t1 t2未结束
    			}
    			System.out.println(Thread.currentThread().getName()+"-++--");
    		}
    	}
    	public void ChangeFlag()
    	{
    		flag = false;
    	}
    }
    public class Main
    {
    	public static void main(String[] args)
    	{
    		StopThread s = new StopThread();
    		Thread t1 = new Thread(s);
    		Thread t2 = new Thread(s);
    		t1.start(); t2.start();
    		int i = 0;
    		while(true)
    		{
    			if(++i == 20)//i达到20后结束全部线程
    			{
    				//s.ChangeFlag();
    				t1.interrupt();
    				t2.interrupt();
    				break;
    			}
    			System.out.println("Main.main"+i);
    		}
    			System.out.println("Final");
    	}
    }


    二、守护线程

    setDaemon(boolean)

    public class Main
    {
    	public static void main(String[] args)
    	{
    		StopThread s = new StopThread();
    		Thread t1 = new Thread(s);
    		Thread t2 = new Thread(s);
    		t1.start(); 
    		t2.setDaemon(true);//守护线程,能够理解为后天线程
    		//后天线程的特点:执行和前台线程一样,和CPU抢夺执行权
    		//           结束:前台线程必须手动结束,后台线程假设全部的前提线程都结束了,后台线程也跟着结束
    		t2.start(); 
    		int i = 0;
    		while(true)
    		{
    			if(++i == 20)//i达到20后结束全部线程
    			{
    				//s.ChangeFlag();
    				t1.interrupt();
    				//t2.interrupt();
    				break;
    			}
    			
    			System.out.println("Main.main"+i);
    		}
    			System.out.println("Final");
    	}
    }

    守护线程简单理解:比方说(英雄联盟)LOL。我方英雄须要守护我方的防御塔,塔没了,守护线程也就不是必需存在了

    三、线程的其它方法

    1.join()

    2.setPriority()


    class Demo implements Runnable
    {
    	public void run()
    	{
    		for(int i = 0;i<20;i++)
    			System.out.println(Thread.currentThread().getName()+"..."+i);
    	}
    }
    
    public class Main
    {
    	public static void main(String[] args)throws Exception
    	{
    		Demo d = new Demo();
    		Thread t1 = new Thread(d);
    		Thread t2 = new Thread(d);
    		t1.start();
    		t1.join();//t1线程要申请增加进来。执行。也就是t1不完,t2 和 主线程 就不能执行。
    		//暂时假如一个线程,就要用join方法
    		t2.start();//假设join放在t2.start()后面,那么主线程仅仅等待t1完毕后执行,而t1和t2互相争夺执行权
    		for(int i = 0;i<20;i++)
    			System.out.println(Thread.currentThread().getName()+".."+i);
    	}
    }

    优先级:setPriority

    class Demo implements Runnable
    {
    	public void run()
    	{
    		for(int i = 0;i<20;i++)
    			System.out.println(Thread.currentThread().toString()+"..."+i);
    	}
    }
    
    public class Main
    {
    	
    	public static void main(String[] args)throws Exception
    	{
    		Demo d = new Demo();
    		
    		Thread t1 = new Thread(d);
    		Thread t2 = new Thread(d);
    		t1.start();
    		t2.start();
    		t2.setPriority(Thread.MAX_PRIORITY);
    		// Thread.MIN_PRIORITY优先级最小1
    		//Thread.MAX_PRIORITY 有效级最大10
    		//Thread.NORM_PRIORITY 默认优先级 5
    		for(int i = 0;i<20;i++)
    			System.out.println(Thread.currentThread()+".."+i);
    	}
    }

    3.线程组

    把10个线程放一个组里。假设中断这一组线程。那么这10个线程都中断了

    4.yield()暂停当前正在运行的线程,并运行其它线程


    class Demo implements Runnable
    {
    	public void run()
    	{
    		for(int i = 0;i<20;i++)
    			{
    			System.out.println(Thread.currentThread().toString()+"..."+i);
    		Thread.yield();
    			}
    	}
    }

    public class Main
    {
    	
    	public static void main(String[] args)throws Exception
    	{
    		new Thread()//线程子类
    		{
    			public void run()
    			{
    				for(int i = 0;i<20;i++)
    				{
    				 System.out.println(Thread.currentThread().getName()+"x = "+i);
    				}
    			}
    		}.start();
    		
    		for(int i = 0;i<20;i++)
    		{
    		 System.out.println(Thread.currentThread().getName()+"y = "+i);
    		}
    		Runnable r = new Runnable() 
    		{
    			public void run() 
    			{
    				for(int i = 0;i<20;i++)
    				{
    				 System.out.println(Thread.currentThread().getName()+"z = "+i);
    				}
    			}
    		};
    		new Thread(r).start();
    	}
    }

    多线程面试题:

    1.

    class Text implements Runnable
    {
    	public void run(Thread t)
    	{
    		
    	}
    }
    //是否编译失败?假设失败错误在哪?

    失败,没有实现run方法的覆盖

    改法一:

    abstract class Text implements Runnable
    {
    	public void run(Thread t)
    	{
    		
    	}
    }

    改法二:重载,进行覆盖


    class Text implements Runnable
    {
    	public void run()
    	{
    		System.out.println("Text.run()1");
    	}
    	public void run(Thread t)
    	{
    		System.out.println("Text.run()2");
    	}
    }
    2.

    public class Main
    {
    	
    	public static void main(String[] args)throws Exception
    	{
    	
    		new Thread(new Runnable() 
    		{
    			public void run() {
    				// TODO Auto-generated method stub
    				System.out.println("Runnable run");
    			}
    		})
    		{
    			public void run()
    			{
    				System.out.println("Thread run");
    			}
    		}.start();//这段代码编译能通过吗?假设能打印哪一句
    	}
    }
    打印Thread run
    以子类为主,没有子类以父类为主




    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    spring boot 配置时区差别
    概率期望
    Euler函数与Euler定理
    素数&筛法
    等差子序列
    8.19 T2
    8.19 T1
    量化交易
    挺进

  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4909121.html
Copyright © 2011-2022 走看看