Java:线程常用方法

join方法

 

join方法:执行该方法的线程进入阻塞状态,直到调用该方法的线程结束后再由阻塞转为就绪状态。

注:当循环执行到i为2时该行代码执行,CounterThread所创建线程进入阻塞状态,直到timeThread变量所对应线程结束,    CounterThread所创建线程才能再次进入就绪状态,进而进入执行状态。

注意:

线程对象在调用join方法前必须先调用start方法,否则该线程永远不会进入执行状态。

interrupt方法

 

interrupt方法:

结束线程在调用Object类的wait方法或该类的join方法、sleep方法过程中的阻塞状态,并在调用wait、join和sleep方法处产生InterruptedException异常。

注:理论上beforeTime和afterTime应该相差30秒,但因为该线程类的对象在1秒后执行了interrupt方法而使得该线程对象提前结束了阻塞状态,从而导致了beforeTime和afterTime相差少于30秒

注:当线程执行该行代码后,线程进入阻塞状态;但由于10秒后主线程执行了“counterThread.interrupt();”代码使得该线程阻塞状态结束。该行代码的执行会结束counterThread线程的阻塞状态。

wait()—痴汉方法

wait()方法就是使线程停止运行,会释放对象锁。

wait()方法是从运行态回阻塞态。
notifi( ) 方法是从阻塞态回运行态。

    wait()方法会使当前线程调用该方法后进行等待,并且将该线程置入锁对象的等待队列中,直到接到通知或被中断为止。
    wait()方法只能在同步方法或同步代码块中调用,如果调用wait()时没有适当的锁,会抛出异常。
    wait()方法执行后,当前线程释放锁,其他线程可以竞争该锁。

    wait()之后的线程继续执行有两种方法:

    调用该对象的notify()方法唤醒等待线程。
    线程等待时调用interrupt()中断该线程。

wait(long time) :如果到了预计时间还未被唤醒,线程将继续执行。

class MyThread implements Runnable{
    private Object object;
    private boolean flag;

    public MyThread(Object object, boolean flag) {
        this.object = object;
        this.flag = flag;
    }

    public void waitMethod() {
        synchronized (object) {
            System.out.println("wait方法开始..." + Thread.currentThread().getName());
            try {
                object.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("wait方法结束..." + Thread.currentThread().getName());
        }
    }
    public void notifyMethod(){
        synchronized (object) {
            System.out.println("notify方法开始..." + Thread.currentThread().getName());
            object.notify();
            System.out.println("notify方法结束..." + Thread.currentThread().getName());
        }
    }
    public void run(){
        if(flag){
           this.waitMethod();
        }else{
           this.notifyMethod();
        }
    }
}
public class Object {
    public static void main(String[] args)throws InterruptedException{
        Object obj = new Object();
        MyThread thread1 = new MyThread(obj,true);
        MyThread thread2 = new MyThread(obj,false);
        Thread waitThread = new Thread(thread1,"等待线程");
        Thread notifyThread = new Thread(thread2,"唤醒线程");
        waitThread.start();
        Thread.sleep(1000);
        notifyThread.start();
    }
}

运行结果:
wait方法开始...等待线程
notify方法开始...唤醒线程
notify方法结束...唤醒线程
wait方法结束...等待线程
 

2. notify()方法

  1. notify()方法必须在同步方法或同步代码块中调用,用来唤醒等待在该对象上的线程,如果有多个线程等待,则任意挑选一个线程唤醒。
  2. notify()方法执行后,唤醒线程不会立刻释放锁,要等唤醒线程全部执行完毕后才释放对象锁。
  3. class MyThread implements Runnable{
        private Object object;
        private boolean flag;

        public MyThread(Object object, boolean flag) {
            this.object = object;
            this.flag = flag;
        }

        public void waitMethod() {
            synchronized (object) {
                System.out.println("wait方法开始..." + Thread.currentThread().getName());
                try {
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("wait方法结束..." + Thread.currentThread().getName());
            }
        }
        public void notifyMethod(){
            synchronized (object) {
                System.out.println("notify方法开始..." + Thread.currentThread().getName());
                object.notify();
                System.out.println("notify方法结束..." + Thread.currentThread().getName());
            }
        }
        public void run(){
            if(flag){
               this.waitMethod();
            }else{
               this.notifyMethod();
            }
        }
    }
    public class Object {
        public static void main(String[] args)throws InterruptedException{
            Object obj = new Object();
            MyThread thread1 = new MyThread(obj,true);
            MyThread thread2 = new MyThread(obj,false);
            for(int i = 0;i<5;i++) {
                Thread threadi = new Thread(thread1, "等待线程"+i);
                threadi.start();
            }
            Thread notifyThread = new Thread(thread2,"唤醒线程");
            Thread.sleep(1000);
            notifyThread.start();
        }
    }
    wait方法开始...等待线程0
    wait方法开始...等待线程1
    wait方法开始...等待线程2
    wait方法开始...等待线程3
    wait方法开始...等待线程4
    notify方法开始...唤醒线程
    notify方法结束...唤醒线程
    wait方法结束...等待线程0
    //当有多个线程同时等待时,notify方法任意挑选一个唤醒。
     

 

wait()和notify()均用于同步方法或同步代码块并且必须是内建锁。

3. notifyAll()

唤醒所有在该对象上等待的线程。

class MyThread implements Runnable{
    private Object object;
    private boolean flag;

    public MyThread(Object object, boolean flag) {
        this.object = object;
        this.flag = flag;
    }

    public void waitMethod() {
        synchronized (object) {
            System.out.println("wait方法开始..." + Thread.currentThread().getName());
            try {
                object.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("wait方法结束..." + Thread.currentThread().getName());
        }
    }
    public void notifyMethod(){
        synchronized (object) {
            System.out.println("notify方法开始..." + Thread.currentThread().getName());
            object.notifyAll();
            System.out.println("notify方法结束..." + Thread.currentThread().getName());
        }
    }
    public void run(){
        if(flag){
           this.waitMethod();
        }else{
           this.notifyMethod();
        }
    }
}
public class Object {
    public static void main(String[] args)throws InterruptedException{
        Object obj = new Object();
        MyThread thread1 = new MyThread(obj,true);
        MyThread thread2 = new MyThread(obj,false);
        for(int i = 0;i<5;i++) {
            Thread threadi = new Thread(thread1, "等待线程"+i);
            threadi.start();
        }
        Thread notifyThread = new Thread(thread2,"唤醒线程");
        Thread.sleep(1000);
        notifyThread.start();
    }
}
运行结果:
wait方法开始...等待线程0
wait方法开始...等待线程1
wait方法开始...等待线程2
wait方法开始...等待线程3
wait方法开始...等待线程4
notify方法开始...唤醒线程
notify方法结束...唤醒线程
wait方法结束...等待线程4
wait方法结束...等待线程3
wait方法结束...等待线程2
wait方法结束...等待线程1
wait方法结束...等待线程0
 

 

setDaemon方法

 

setDaemon方法:用于将一个尚未调用线程start方法的线程设置为守护线程。守护线程主要用于为其他线程的运行提供服务(Java中的垃圾回收机制就是守护线程),这种线程属于创建它的线程,守护线程随着主线程的终止而终止。

注:守护线程不是将原来线程改为守护线程,而是本来就是守护线程,别忘了setDaemon方法需要在start方法之前调用。设置本线程为守护线程。

 

注意:

线程中所启动的其他非守护线程线程不会随着该线程的结束而结束。(参见代码2)

 

currentThread方法

 

currentThread方法:返回当前正在执行的线程对象。

注:返回正在执行main方法的线程对象——主线程

 

注意:

请判读备注中代码1、代码2、代码3和代码4。

注:通过运行结果可以发现此方法被一个名为“时间线程”的线程执行

isAlive方法

 

isAlive方法:判定该线程是否处于就绪、运行或阻塞状态,如果是则返回true,否则返回false。

注:当打印线程阻塞时程序一定会先执行main方法中的输出语句,此时输出true;当打印线程阻塞状态结束,此时输出false,由此可见main方法中启动的线程可能晚于主线程结束。

 

其它方法

 

1.void start():使该线程开始启动,Java 虚拟机负责调用该线程的 run() 方法。多次启动一个线程是非法的。

 

2.void sleep(long millis):Thread类静态方法,线程进入阻塞状态,在指定时间(单位为毫秒)到达之后进入就绪状态(Runnable),而非立即进入执行状态。

 

3.void yield():静态方法,当前线程放弃占用CPU资源,回到就绪状态,使其他优先级不低于此线程的线程有机会被执行。

 

4.void setPriority(int newPriority):设置当前线程的优先级,线程优先级越高,线程获得执行的次数越多,Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:

 

①static int MAX_PRIORITY   最高优先级值为10;

 

②static int NORM_PRIORITY   默认优先级值为5;

 

③static int MIN_PRIORITY   最低优先级值为1;

 

5.int getPriority():获得当前线程的优先级。
终止线程——无疾而终

终止线程——暴毙身亡

注:巧妙利用线程对象调用interrupt方法时会引发异常而使得死循环中止

注:巧妙利用线程对象调用interrupt方法时会引发异常而使得死循环中止

4.线程阻塞

    调用sleep()方法,主动放弃占有的CPU,不会释放对象锁。
    调用阻塞式IO方法(read()、write()),在该方法返回前,线程阻塞。
    线程试图获取一个monitor,但该monitor被其他线程所持有导致阻塞。
    线程等待某个通知,即调用wait(),释放对象锁。
    调用线程suspend(),将线程挂起,容易导致死锁,已被废弃。
    这五个线程会从运行状态到阻塞状态。

5. monitor 的两个队列

每个monitor都有两个队列,一个称为同步队列,一个称为等待队列。

    同步队列中存放了因为竞争monitor失败导致阻塞的线程,这些线程等待CPU调度再次竞争锁。
    等待队列存放所有调用wait()方法导致线程等待的线程,唤醒后进入同步队列竞争锁。
 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值