重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本篇内容主要讲解“Java多线程的种类和区别”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java多线程的种类和区别”吧!
创新互联自2013年创立以来,是专业互联网技术服务公司,拥有项目成都网站建设、做网站网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元同心做网站,已为上家服务,为同心各地企业和个人服务,联系电话:18980820575
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 CallableModelimplements 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多线程的种类和区别”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!