Java提高——多线程(二)join、sleep、yield


join、sleep、yield都是Thread类的方法

join线程

join()方法:让“主线程”线程等待“子线程”运行完之后再运行

//子线程
public class son extends Thread(){
        void run(){
        ......
        }
}
//主线程
public class F() extends Thread{
        void run(){
        son s = new son();
        s.start();
        s.join();
        ...
     }
}

如:在主线程中调用子线程s.start()启动子线程并调用s.join(),在调用s.join()之后主线程会一直等待,直到子线程运行完毕之后才接着运行。

源码:

public final synchronized void join(long millis)
throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (millis == 0) {//判断子线程是否还活着
        while (isAlive()) {
            wait(0);//让当前CPU上运行的线程等待
        }
    } else {
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

用事实说话:

class MyThread1 extends Thread{
    public MyThread1(String name) {
        super(name);
    }
    @Override
    public void run(){
        System.out.println(this.getName()+" start\n");
        //延时操作
        for (int i = 0; i < 1000; i++) {

        }
        System.out.println(this.getName()+"finish\n");
    }
}
public class Demo extends Thread {
    public static void main(String[] args) throws InterruptedException {
        MyThread1 t = new MyThread1("myThread");
        t.start();
        t.join();
        System.out.println(currentThread().getName()+" finish");
    }
}


myThread start

myThreadfinish

main finish

结果显示一样

线程睡眠

sleep()方法:让当前线程休眠,指定休眠时间,从“运行状态”进入“休眠(阻塞)状态”。唤醒之后线程进入“就绪状态”等待CPU调度。

class MyThread1 extends Thread{
    public MyThread1(String name) {
        super(name);
    }
    @Override
    public void run(){
        System.out.println(this.getName()+" start\n");
        //延时操作
        for (int i = 0; i < 1000; i++) {
            if(i%4==0){//如果成立线程睡觉100ms
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(this.getName()+"finish\n");
    }
}
public class Demo extends Thread {
    public static void main(String[] args) throws InterruptedException {
        MyThread1 thread = new MyThread1("myThread");
        thread.start();
        thread.join();
        System.out.println(currentThread().getName()+" finish");
    }
}
sleep & wait

wait()的作用也是能够让线程从“运行状态”进入“休眠(阻塞)状态”,同时释放同步锁但是sleep不会释放同步锁

public class SleepLockTest {
   static Object object = new Object();

    public static void main(String[] args) {
        ThreadA ta = new ThreadA("t1");
        ThreadA tb = new ThreadA("t2");
        ta.start();
        tb.start();
    }
    static class ThreadA extends Thread{
        public ThreadA(String name) {
            super(name);
        }
        @Override
        public void run(){
            //获取object对象的同步锁
            synchronized (object){
                for (int i = 0; i < 10; i++) {
                    System.out.println(this.getName()+" "+i);
                    if (i%4==0){
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

ta、tb会获得同一个对象的同步锁,ta在运行中会执行Thread.sleep(100),但是tb不会获得CPU的执行权,因为ta没有释放同步锁。

注释掉同步锁之后:ta、tb可以互相切换

线程让步 

yield():和sleep类似,让线程从“运行状态”到“就绪状态”,但是不会阻塞线程,只是让当前线程停一会儿,让同优先级的其他线程获得被执行的机会但是不保证一定会被执行

yield&wait

1)wait让线程从“运行状态”到“阻塞状态”,yield让线程从“运行状态”到“就绪状态”

2)wait会释放同步锁,yield和sleep一样不会释放同步锁

转载请注明出处:http://www.cnblogs.comskywang12345/p/3479256.html

posted @ 2018-05-07 16:35  惶者  阅读(217)  评论(0编辑  收藏  举报