本篇内容主要讲解“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多线程的种类和区别”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/waterupking/blog/3068059