JavaSE-多线程-32-wait--sleep 区别,停止线程,守护进程,join 作用是什么?面试题


请说一下 wait 和 sleep 区别?

1,wait可以指定时间也可以不指定。
   sleep必须指定时间。

2,在同步中时,对cpu的执行权和锁的处理不同。
(  执行权必须释放,不然电脑就废了!!!!)
    wait:释放执行权,释放锁。
    sleep:释放执行权,不释放锁。

 

class Demo
{

    void show()
    {
        synchronized(this)// 
        {
         
            wait();//t0 t1 t2    都会在这 wait挂着---当 notifyAll 后 t0  t1  t2 都活了,
                                            //具备CPU执行资格 但是此时  t0 t1 t2  还没有持有锁, 没有执行权, t4 退出释放锁
                                          //假设此时 t0 获得锁,t0 执行  ,此时t1 t2 是没办法执行的,除非  t0 结束释放锁。(分析)

        }
    }
    void method()
    {
        synchronized(this)//t4
        {
            //wait();
            notifyAll();
        }//t4
    }
}

class  
{
    public static void main(String[] args) 
    {
        System.out.println("Hello World!");
    }
}
 

 

interrupt 使用

/*
停止线程:
1,stop方法。已经过时 不安全

2,run方法结束

怎么控制线程的任务结束呢?
任务中都会有循环结构,只要控制住循环就可以结束任务。

控制循环通常就用定义标志位来完成。
但是如果线程处于了冻结状态,无法读取标记。如何结束呢?
用notify ?  notify 需要同一个锁 不可取。
[可以使用interrupt()方法将线程从冻结状态wait()强制恢复到运行状态中来,让线程具备cpu的执行资格]。 
当时强制动作会发生了InterruptedException,记得要处理
*/
class StopThread implements Runnable
{
    private boolean flag = true;
    public synchronized void run()//同步
    {
        while(flag)
        {
            try
            {
                wait();//t0 t1一进来就在 wait  等待 此时set  flag 也无效
                                                              // 需要 interrupt()  抛出异常。
            }
            catch (InterruptedException e)
            {
                System.out.println(Thread.currentThread().getName()+"....."+e);
                flag = false;
            }
            
            System.out.println(Thread.currentThread().getName()+"......++++");
        }
    }
    public void setFlag()//设置标志位让线程退出
    {
        flag = false;
    }
}

 

class StopThreadDemo 
{
    public static void main(String[] args) 
    {
        StopThread st = new StopThread();

        Thread t1 = new Thread(st);
        Thread t2 = new Thread(st);

        t1.start();
        t2.setDaemon(true);
        t2.start();


        int num = 1;
        for(;;)
        {
            if(++num==50)
            {
//                st.setFlag();
                t1.interrupt();
//                t2.interrupt();
                break;// break 退出 只是主线程退出 子线程 还在运行 所以电泳 st.setFlag();
            }
            System.out.println("main...."+num);
        }

        System.out.println("over");
    }
}
 

 守护进程 (后台线程)

 

前台线程退出后台线程也会跟着退出不管这个线程是不是被冻结了。 

package thread;

class   DaemonTest   implements   Runnable{
    @Override
    public void run() {
        System.out.println(" setDaemon");
        try{
            this.wait();//冻结
        }catch ( InterruptedException e){
            e.printStackTrace();
        }

    }
}

public class DaemonDemo {


    public static void main(String[] args) {
         DaemonTest  daemonTest =new DaemonTest();
         Thread  thread =new Thread(daemonTest);
         //启动之前调用setDaemon --后台线程
         thread.setDaemon(true);
         thread.start();
         System.out.println("main over");

    }
}

 

class   DaemonTest   implements   Runnable{

     Object  obj=new Object();
    @Override
    public void run() {
        synchronized (obj){
            while (true){
                System.out.println(" setDaemon");
                try{
                    //  this.wait();//冻结
                    obj.wait();
                }catch ( InterruptedException e){
                    e.printStackTrace();
                }
            }
        }

    }
}
public class DaemonDemo {
    public static void main(String[] args) {
         DaemonTest  daemonTest =new DaemonTest();
         Thread  thread =new Thread(daemonTest);
         //启动之前调用setDaemon --后台线程
         thread.setDaemon(true);
         thread.start();
         System.out.println("main over");
    }
}

 Join 方法用法

 

例如在 main 函数一个线程t1 调用这个方法 ,那么 main 函数会释放CPU执行权 被冻结,等待这个t1 线程执行结束后再获得执行资格。

Demo:

package thread;

import java.awt.image.ImagingOpException;

class Join implements  Runnable {

    @Override
    public void run() {
        for(int i=0;i<10;i++){
            System.out.println("等待 Join 执行完"+i);
        }
        System.out.println("Join 插入执行完成");
    }

}


public class JoinDemo    {

    public static void main(String[] args) {

      Join  join =new Join();
      Thread  thread =new Thread(join);
      thread.start();
      try{
          thread.join();
      }catch (InterruptedException e){
          System.out.println(" intrrupt");
      }
      System.out.println("main over");
    }

}

执行结果:等待 Join 执行完0
等待 Join 执行完1
等待 Join 执行完2
等待 Join 执行完3
等待 Join 执行完4
等待 Join 执行完5
等待 Join 执行完6
等待 Join 执行完7
等待 Join 执行完8
等待 Join 执行完9
Join 插入执行完成
main over

如果有:

  t1.start();

t2.start();

t1.join();

 那么这时main 是等待 t1 线程结束。

优先级:

1--5--10

 

优先级代表获取CPU 执行权的几率。(级别 1-10)

toString 方法

 

 面试题1  :

class  Test  implements  Runnable{

public  void run(Thread  t){}

}//如果错误错误发生在哪一行?

答案:错误在第一行,Test 不是抽象类,并且未覆盖 Runnable 中的抽象方法。应该被 abstract  修饰。

面试题2 :

package thread;

public class ThreadTest {

    public static void main(String[] args) {
        new  Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(" runnable  run ");
            }
        }) {
            public  void  run()
            {
                System.out.println(" sub  run ");
            }
        }.start();
    }
}

输出结果:sub   run    以子类为主

如果  没有  { public void run() { System.out.println(" sub run "); } 则输出   runnable   run   以任务为主

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值