《Java多线程编程核心技术》读后感(十一)

《Java多线程编程核心技术》读后感(十一)

 

 

 

 

 

 

方法join的使用

在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束。这时,如果主线程想等待子线程执行完之后再结束,比如子线程处理一个数据,主线程要取得这个数据中的值,就要用到join()方法了。

学习join前的铺垫

package Third;

public class MyThread extends Thread {

    @Override
    public void run() {
        try {
            int secondValue = (int) (Math.random() * 10000);
            System.out.println(secondValue);
            Thread.sleep(secondValue);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
package Third;

public class Test {

    public static void main(String[] args) {

        MyThread threadTest = new MyThread();
        threadTest.start();

        // Thread.sleep(?)
        System.out.println("我想当threadTest对象执行完毕后我再执行");
        System.out.println("但上面代码中的sleep()中的值应该写多少呢?");
        System.out.println("答案是:根据不能确定:)");
    }

}

《Java多线程编程核心技术》读后感(十一)

sleep()多少不能确定

用join()方法来解决

package Third;

public class Test {

    public static void main(String[] args) {
        try {
            MyThread threadTest = new MyThread();
            threadTest.start();
            threadTest.join();

            System.out.println("我想当threadTest对象执行完毕后我再执行,我做到了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

《Java多线程编程核心技术》读后感(十一)

方法join的作用是使所属的线程对象X正常执行run()方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后再继续执行线程z后面的代码。

方法join具有使线程排队运行的作用,有些类似同步的运行效果。join与synchronized的区别是:join在内部使用wait()方法进行等待,而synchronized关键字使用的是“”对象监视器“”原理做为同步。

方法join与异常

在join过程中,如果当前线程对象被中断,则当前线程出现异常

package Third;

public class ThreadA extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            String newString = new String();
            Math.random();
        }
    }
}
package Third;

public class ThreadB extends Thread {

    @Override
    public void run() {
        try {
            ThreadA a = new ThreadA();
            a.start();
            a.join();

            System.out.println("线程B在run end处打印了");
        } catch (InterruptedException e) {
            System.out.println("线程B在catch处打印了");
            e.printStackTrace();
        }
    }

}
package Third;

public class ThreadC extends Thread {

    private ThreadB threadB;

    public ThreadC(ThreadB threadB) {
        super();
        this.threadB = threadB;
    }

    @Override
    public void run() {
        threadB.interrupt();
    }

}

《Java多线程编程核心技术》读后感(十一)

《Java多线程编程核心技术》读后感(十一)

方法join(long)使用

参数是设定等待的时间

package Third;

public class MyThread extends Thread {

    @Override
    public void run() {
        try {
            System.out.println("begin Timer=" + System.currentTimeMillis());
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
package Third;

public class Test {

    public static void main(String[] args) {
        try {
            MyThread threadTest = new MyThread();
            threadTest.start();

             threadTest.join(2000);//只等2秒
            //Thread.sleep(2000);

            System.out.println("  end timer=" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

《Java多线程编程核心技术》读后感(十一)

package Third;

public class Test {

    public static void main(String[] args) {
        try {
            MyThread threadTest = new MyThread();
            threadTest.start();

            //threadTest.join(2000);//只等2秒
            Thread.sleep(2000);

            System.out.println("  end timer=" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

《Java多线程编程核心技术》读后感(十一)

 

《Java多线程编程核心技术》读后感(十一)

 方法join(long)与sleep(long)的区别

方法join(long)的功能在内部是使用wait(long)方法来实现的,所以join(long)方法具有释放锁的特点。

《Java多线程编程核心技术》读后感(十一)

从源代码中可以了解到,当执行wait(long)方法后,当前线程的锁被释放,那么其他线程就可以调用此线程中的同步方法了。

而Thread.sleep(long)方法却不释放锁,下面的实验证Thread.sleep(long)不释放锁的特点

package Third;

public class ThreadA extends Thread {

    private ThreadB b;

    public ThreadA(ThreadB b) {
        super();
        this.b = b;
    }

    @Override
    public void run() {
        try {
            synchronized (b) {
                b.start();
                Thread.sleep(6000);
                // Thread.sleep()不释放锁
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
package Third;

public class ThreadB extends Thread {

    @Override
    public void run() {
        try {
            System.out.println("   b run begin timer="
                    + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("   b run   end timer="
                    + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    synchronized public void bService() {
        System.out.println("打印了bService timer=" + System.currentTimeMillis());
    }

}
package Third;

public class ThreadC extends Thread {

    private ThreadB threadB;

    public ThreadC(ThreadB threadB) {
        super();
        this.threadB = threadB;
    }

    @Override
    public void run() {
        threadB.bService();
    }

}
package Third;

public class Run {

    public static void main(String[] args) {

        try {
            ThreadB b = new ThreadB();

            ThreadA a = new ThreadA(b);
            a.start();

            Thread.sleep(1000);

            ThreadC c = new ThreadC(b);
            c.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

《Java多线程编程核心技术》读后感(十一)

《Java多线程编程核心技术》读后感(十一)

下面验证Thread.sleep(long)释放锁的特点

更改上面的ThreadA.java

package Third;

public class ThreadA extends Thread {

    private ThreadB b;

    public ThreadA(ThreadB b) {
        super();
        this.b = b;
    }

    @Override
    public void run() {
        try {
            synchronized (b) {
                b.start();
                b.join();// 说明join释放锁了
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
                    String newString = new String();
                    Math.random();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

《Java多线程编程核心技术》读后感(十一)

《Java多线程编程核心技术》读后感(十一)

方法join()后面的代码提前运行:出现意外

package Third;

public class ThreadA extends Thread {
    private ThreadB b;

    public ThreadA(ThreadB b) {
        super();
        this.b = b;
    }

    @Override
    public void run() {
        try {
            synchronized (b) {
                System.out.println("begin A ThreadName="
                        + Thread.currentThread().getName() + "  "
                        + System.currentTimeMillis());
                Thread.sleep(5000);
                System.out.println("  end A ThreadName="
                        + Thread.currentThread().getName() + "  "
                        + System.currentTimeMillis());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
package Third;

public class ThreadB extends Thread {
    @Override
    synchronized public void run() {
        try {
            System.out.println("begin B ThreadName="
                    + Thread.currentThread().getName() + "  "
                    + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("  end B ThreadName="
                    + Thread.currentThread().getName() + "  "
                    + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
package Third;

public class Run1 {
    public static void main(String[] args) {
        try {
            ThreadB b = new ThreadB();
            ThreadA a = new ThreadA(b);
            a.start();
            b.start();
            b.join(2000);
            System.out.println("                    main end "
                    + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

《Java多线程编程核心技术》读后感(十一)

方法join()后面的代码提前运行:解释意外

package Third;

public class RunFirst {

    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        ThreadA a = new ThreadA(b);
        a.start();
        b.start();
        System.out.println("   main end=" + System.currentTimeMillis());
    }

}

《Java多线程编程核心技术》读后感(十一)

《Java多线程编程核心技术》读后感(十一)

 

 《Java多线程编程核心技术》读后感(十一)

 

《Java多线程编程核心技术》读后感(十一)

 《Java多线程编程核心技术》读后感(十一)

《Java多线程编程核心技术》读后感(十一)

《Java多线程编程核心技术》读后感(十一)

《Java多线程编程核心技术》读后感(十一)

 

posted on 2017-11-18 21:47 Michael2397 阅读(...) 评论(...) 编辑 收藏