千家信息网

Java多线程的种类和区别

发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,本篇内容主要讲解"Java多线程的种类和区别",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java多线程的种类和区别"吧!1.多线程种类和区别Thread
千家信息网最后更新 2025年01月24日Java多线程的种类和区别

本篇内容主要讲解"Java多线程的种类和区别",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java多线程的种类和区别"吧!

1.多线程种类和区别

Thread类、runnable接口、callable接口,使用callable时,需要重写call方法,使用FutureTask调用,使用get方法可以获取返回值。 Callable与Thread、Runnable最大的不同是Callable能返回一个异步处理的结果Future对象并能抛出异常,而其他两种不能 runnable方式实现更为灵活,耦合度低,是比较常用的方式。面向接口编程也是设计模式六大原则的核心

package thread;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class CallableModel implements Callable {    @SuppressWarnings("unchecked")    @Override    public V call() throws Exception {        // TODO Auto-generated method stub        System.out.println("重写call方法");        return (V) "调用callable,有返回值";    }    public static void main(String[] args) throws InterruptedException, ExecutionException {        FutureTask futureTask = new FutureTask<>(                new CallableModel());        Thread thread = new Thread(futureTask);        thread.start();        System.out.println(futureTask.get());    }}

2.多线程的好处

发挥多核CPU的优势,放置阻塞,方便建模等

3.start和run的区别 只有调用start才会表现出多线程特点。run只是一个普通方法,调用时多个线程会同步执行。

3.start和run的区别 只有调用start才会表现出多线程特点。run只是一个普通方法,调用时多个线程会同步执行。

4.runnable和callable的区别 callable可以和Future、FutureTask配合可以用来获取异步执行的结果,call方法是有返回值的,多线程充满未知性,使用futureTask来获取执行结果,在等待太长时间未返回结果时取消此线程是非常有必要的

5.CyclicBarrier和CountDownLatch的区别-栅栏锁 都在java.util.concurrent下,都可以用来表示代码运行到某个点上,CyclicBarrier用于等待一组事件完成,然后启动下一个事件,例如一组运动员准备好之后,发出跑的命令,CountDownLatch允许一个或者多个线程等待一组事件的产生。 1)CyclicBarrier的某个线程运行到某个点上之后,该线程即停止运行,直到所有的线程都到达了这个点,所有线程才重新运行;CountDownLatch则不是,某线程运行到某个点上之后,只是给某个数值-1而已,该线程继续运行。

2)CyclicBarrier只能唤起一个任务,CountDownLatch可以唤起多个任务。

3)CyclicBarrier可重用(通过调用reset方法),CountDownLatch不可重用,计数值为0该CountDownLatch就不可再用了。 6.CyclicBarrier代码示例

package thread;;/** *      * 项目名称:test   * 类名称:ThreadModel    * 类描述:  通过集成Thread实现多线程 * 创建人:@author 王丰生 * 创建时间:2019年7月1日 下午1:00:46  * 修改人:@author 王丰生 * 修改时间:2019年7月1日 下午1:00:46    * 修改备注: * @version      * */public class ThreadModel extends Thread {    private java.util.concurrent.CyclicBarrier cyclicBarrier;    /**     * Thread实际是实现了runnable接口的一个类,需要重写run方法,调用start方法启动     */    public ThreadModel(java.util.concurrent.CyclicBarrier cyclicBarrier) {        // TODO Auto-generated constructor stub        this.cyclicBarrier = cyclicBarrier;    }    @Override    public void run() {        // TODO Auto-generated method stub        super.run();        try {            System.out.println(Thread.currentThread().getName() + "开始等待");            cyclicBarrier.await();            System.out.println(Thread.currentThread().getName() + "开始执行");            Thread.sleep(1000 * 2);            System.err.println(Thread.currentThread().getName() + "执行完毕");        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public static void main(String[] args) {        int threadCount = 3;        java.util.concurrent.CyclicBarrier cyclicBarrier = new java.util.concurrent.CyclicBarrier(                threadCount);        for (int i = 0; i < threadCount; i++) {            System.out.println("创建工作线程" + i);            ThreadModel threadModel = new ThreadModel(cyclicBarrier);            threadModel.start();        }    }}

7.CountDownlatch代码示例 主线程内启动两个线程之后,调用await方法,线程1执行完毕。调用countdown,线程2执行完毕调用countdown,代表线程都执行完,则释放await的锁,继续向下执行

/** * 看大夫任务 * Created by jiapeng on 2018/1/7. */public class SeeDoctorTask implements Runnable{    private CountDownLatch countDownLatch;    public SeeDoctorTask(CountDownLatch countDownLatch){        this.countDownLatch = countDownLatch;    }    @Override    public void run() {        try {            Thread.sleep(3000);            System.out.println("看大夫成功,大夫给开了些药单子");        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            if(countDownLatch != null) {                countDownLatch.countDown();            }        }    }}/** * 排队的任务 * Created by jiapeng on 2018/1/7. */public class QueueTask implements Runnable{    private CountDownLatch countDownLatch;    public QueueTask(CountDownLatch countDownLatch){        this.countDownLatch = countDownLatch;    }    @Override    public void run() {        try {            Thread.sleep(5000);            System.out.println("排队成功,可以开始交费");        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            if(countDownLatch != null) {                countDownLatch.countDown();            }        }    }}/** * 配媳妇去看病,轮到媳妇看大夫时 * 我就开始去排队准备交钱了。 * Created by jiapeng on 2018/1/7. */public class MainClient {    public static void main(String[] args) throws Exception{        long now = System.currentTimeMillis();        CountDownLatch countDownLatch = new CountDownLatch(2);        Executor executor = Executors.newFixedThreadPool(2);        executor.execute(new SeeDoctorTask(countDownLatch));        executor.execute(new QueueTask(countDownLatch));        countDownLatch.await();        System.out.println("over,回家 cost:"+(System.currentTimeMillis()-now));    }}

8.volatile关键字 volatile修饰的变量保证了其在多线程之内的可见性,相当于一个轻量级的sychronized,多线程读到的此变量一定都是最新的。

9.什么是线程安全 多线程状态下获得和单线程下永远能获得同样的结果,则代表是线程安全的,分为

10.获取线程堆栈dump文件 死循环、死锁、阻塞等问题,需要打印线程堆栈,可以使用getStackTrace()方法,使用jps获取线程pid,用jstack pid命令,或者kill-3 pid来获取线程堆栈信息

11.线程出现了异常 如果出现异常且未被捕获,则线程会终止,如果这个线程持有某个某个对象的监视器,那么这个对象监视器会被立即释放

到此,相信大家对"Java多线程的种类和区别"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0