Java多线程14 多线程里的细节

一:sleep  和wait  的区别(sleep  和监视器的区别)

相同点:可以让线程处于冻结状态

不同点:

sleep   是定义在Thread  类中的一个静态方法

wait     是定义在Object   类中的方法

  1. sleep 必须要指定时间////wait 可以指定时间也可以不指定时间
  2. sleep 时间到,线程就处于临时阻塞或者是运行状态///wait 如果是没有设置时间,必须要通过 notify 或者 notifyAll  来唤醒
  3. sleep  不一定要定义在同步中。sleep 是定义在 Thread 类中的一个静态方法///wait  必须要定义使用在同步中,而且要加上锁
  4. 定义在同步中时:执行到 sleep   wait   都会释放CPU的执行权
  • sleep     不会释放锁
  • wait        一定会释放锁(多条线程执行同一个函数,可以很好的解释)

二:线程如何停止

 查看API中有一个stop 方法。但是已经弃用。提供的解决办法:修改某些变量以指示目标线程应该停止来达到停止线程 

run 方法中通常都定义了循环,只要控制住循环就可以了。设置变量通过标识指示循环结束,线程就结束了

示例代码:

package Thread;
//演示线程停止
class SDemo implements Runnable{
   private boolean flag=true;
    public void run(){
        while(flag){
            System.out.println(Thread.currentThread().getName()+"...... ");
        }
    }
    public void ChangeFlag(){
        flag= false;
    }
}
public class StopDemo {
    public static void main(String[] args){
        SDemo r = new SDemo();
        Thread t1= new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
        int x= 0;
        try{Thread.sleep(100);}catch(InterruptedException e){}
       while(true){
           if(++x==50){
               r.ChangeFlag();
               break;
           }
         //  System.out.println("main   "+x);
       }
       System.out.println(x);
        System.out.println("主线程结束!!!");
    }
}

当线程处于冻结状态无法判断标记时如何让此线程停止:API中提供的方法为使用interrupt()  方法

 

class SDemo implements Runnable{
   private boolean flag=true;
    public synchronized void run(){
        while(flag){
            try{this.wait();}catch(InterruptedException e){}
            System.out.println(Thread.currentThread().getName()+"...... ");
        }
    }
    public void ChangeFlag(){
        flag= false;
    }
}

此时线程就冻结了。(死锁)

interrupt(): (API)

其实就是将线程的冻结状态清除。让线程继续执行(重新恢复执行资格),必须依赖其他具备执行资格和执行权的线程(因为冻结的线程不具备CPU的执行权是无法做任何执行的)

书写格式:线程对象.interrupt();

package Thread;
//冻结的线程如何停止的
class InDemo implements Runnable{
    private boolean flag= true;
    public synchronized void run(){
        while(flag){
            try{this.wait();}catch(InterruptedException e){
                System.out.println(Thread.currentThread().getName()+"......."+e.toString());
                ChangeFlag();
            }
            System.out.println(Thread.currentThread().getName()+"........");
        }
    }
    private void ChangeFlag(){
        flag=false;
    }
}
public class InterruptDemo {
    public static void main(String[] args){
        InDemo in = new InDemo();
        Thread t1= new Thread(in);
        Thread t2= new Thread(in);
        t1.start();
        t2.start();
        int x=0;
      //  try{Thread.sleep(100);}catch(InterruptedException e){}
        while(true){
            if(++x==50){
                //强制唤醒t1 t2
                t1.interrupt();
                t2.interrupt();
                break;
            }
            System.out.println("main..."+x);
        }
        System.out.println("主函数结束!!");
    }
}

结合了异常,这里也是利用了异常。线程一运行就会冻结,当主线程循环执行到指定次数时就会强制性的解除现成的冻结,线程继续执行,执行解决异常的方案,就会修改标记。当线程再次执行时,标记已经都变成了  false   不会进入循环。线程停止。

三:守护线程

守护线程是后台线程,一般我们创建的线程都是前台线程

前台和后台线程运行时都是一样的,获取CPU的执行权,只是结束的时候有一些不同,

前台线程要通过run 方法结束,线程结束///////后台线程也可以通过run  方法结束,线程结束。但是还有另外一种情况——当进程中所有的前台线程都结束了,无论后台线程处于什么状态,都会结束,从而进程就会结束

进程结束依赖的是前台线程

API中提供了一种将前台线程转化为后台的方法(在线程开起之前标记为后台线程)

      • public final void setDaemon(boolean on)

        将此线程标记为daemon线程或用户线程。 当运行的唯一线程都是守护进程线程时,Java虚拟机将退出。

Java虚拟机就是一个进程,当里面的前台线程全部结束后,这个进程也会结束

  Thread t1= new Thread(in);
        Thread t2= new Thread(in);
        t1.start();
        t2.setDaemon(true);//将t2 标记为后台线程,当主线程和t1 结束后,t2 一定会结束
        t2.start();

四:优先级和线程组

API中的解释

  • 每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行。 每个线程可能也可能不会被标记为守护程序。 当在某个线程中运行的代码创建一个新的Thread对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时新的线程才是守护线程。

    当Java虚拟机启动时,通常有一个非守护进程线程(通常调用某些指定类的名为main的方法)。

    t2.start();
        System.out.println(Thread.currentThread().toString());//获得主线程的线程名称,优先级和线程组

优先级:被CPU优先处理的频率

优先级的表示:用数字表示(1-10).其中默认的初始优先级5 最明显的三个优先级1  5   10

猜你喜欢

转载自blog.csdn.net/Stitch__/article/details/81943771