本篇内容主要讲解“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<V> implements Callable<V> { @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<String> futureTask = new FutureTask<>( new CallableModel<String>()); 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多线程的种类和区别”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。