java多线程理解与实现方式

1.通过继承thread类,覆写run方法来实现多线程。

 1 public class Mytest {
 2     public static void main(String[] args) {
 3         Thread myThread1 = new MyThread1();
 4         Thread myThread2 = new MyThread1();
 5         //调用start方法
 6         myThread1.start();
 7         myThread2.start();
 8         //调用run方法
 9         //myThread1.run();
10         //myThread2.run();
11     }
12 }
13
14 class MyThread1 extends Thread {
15     public void run(){
16         for(int i=0; i<10; i++){
17             System.out.println(i);
18             try {
19                 Thread.sleep(10);
20             } catch (InterruptedException e) {
21                 // TODO Auto-generated catch block
22                 e.printStackTrace();
23             }
24         }
25
26     }
27 }

此时应该调用start()方法来启动一个线程,这样该线程就处于就绪状态,thread类会调用run()方法来执行该线程,这样上面的代码就会交替执行输出。

如果直接使用run()方法,它仅仅只是调用了一个方法,这个方法只是在主线程依次执行,这样上面的代码就会依次输出。

2.通过实现Runnable接口来实现多线程。(其实Thread类也是实现了Runable接口,public class Thread extends Object implements Runnable)

 1 public class Mytest2 {
 2     public static void main(String[] args) {
 3         MyThread2 mythread = new MyThread2();
 4         Thread thread1 = new Thread(mythread);
 5         Thread thread2 = new Thread(mythread);
 6         //执行start方法
 7         thread1.start();
 8         thread2.start();
 9         //执行run方法
10         //thread1.run();
11         //thread2.run();
12     }
13
14 }
15
16 class MyThread2 implements Runnable {
17     @Override
18     public void run() {
19         for(int i=0; i<10; i++){
20             System.out.println(i);
21             try {
22                 Thread.sleep(10);
23             } catch (InterruptedException e) {
24                 // TODO Auto-generated catch block
25                 e.printStackTrace();
26             }
27         }
28
29     }
30
31 }

因为实现Runable子类是没有start()方法的,所以通过Thread类的public Thread(Runnable target)构造方法来实现。

在实际的项目中,因为java只能继承单一类,可实现多接口,所以通常用继承Runable接口来实现多线程。

在继承Thread类和实现Runable接口还有一个重要的区别,后者能很方便的实现资源的共享。后者可以通过

MyThread2 mythread = new MyThread2();
Thread thread1 = new Thread(mythread);
Thread thread2 = new Thread(mythread);

让thread1和thread2共享资源,因为他们传的是同一个mythread。

3.使用Executor框架来实现多线程。

为什么要用到Executor框架呢?

Executor框架可以很方便的实现有返回结果的多线程,以上的两种方法都是没有返回值的。

 1 public class Mytest3 {
 2     public static void main(String[] args) {
 3         //设定线程的数量
 4         int threadSize = Runtime.getRuntime().availableProcessors(); 5         //通过Executors获取一个线程数量固定的线程池
 6         ExecutorService threadPool = Executors.newFixedThreadPool(threadSize);
 7         //用来存放返回结果
 8         List<Future> fList = new ArrayList<Future>();
 9         //提交任务到线程池
10         for(int i=0; i<10; i++){
11             Future f = threadPool.submit(new CallFunction(i, "我的线程" + i));
12             fList.add(f);
13         }
14         threadPool.shutdown();
15         //获取返回的结果
16         for(Future f : fList){
17             try {
18                 System.out.println(f.get().toString());
19             } catch (InterruptedException e) {
20                 // TODO Auto-generated catch block
21                 e.printStackTrace();
22             } catch (ExecutionException e) {
23                 // TODO Auto-generated catch block
24                 e.printStackTrace();
25             }
26         }
27     }
28
29 }
30 class CallFunction implements Callable<Object> {
31     //线程id
32     private int taskId;
33     //线程内容
34     private String taskContent;
35
36     CallFunction(int taskId, String taskContent){
37         this.taskId = taskId;
38         this.taskContent = taskContent;
39     }
40
41     //每个线程调用的方法
42     @Override
43     public Object call() throws Exception {
44         String result = taskId + ":" + taskContent;
45         return result;
46     }
47
48 }

以上代码主要设计到了ExecutorService、CallFunction、Future。

ExecutorService主要是通过Executors.newFixedThreadPool获取一个固定的线程池

CallFunction是实现了Callable接口,与Runable接口不同的是,Callable能返回值,而Runable不能返回值

Future是用于接收返回值,在submit的时候它是多线程并行的提交,而在使用Future的get方法的时候,它会串行的等待线程执行完毕直到返回结果。

时间: 2024-08-03 03:20:13

java多线程理解与实现方式的相关文章

使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点?

我感觉很多项目使用java或者c的多线程库+线程安全的queue数据结构基本上可以实现goroutine+channel开发能达到的需求,所以请问一下为什么说golang更适合并发服务端的开发呢?使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点? 使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点? >> golang 这个答案描述的挺清楚的:http://www.goodpm.net/postreply

从JAVA多线程理解到集群分布式和网络设计的浅析

对于JAVA多线程的应用非常广泛,现在的系统没有多线程几乎什么也做不了,很多时候我们在何种场合如何应用多线程成为一种首先需要选择的问题,另外关于java多线程的知识也是非常的多,本文中先介绍和说明一些常用的,在后续文章中如果有必要再说明更加复杂的吧,本文主要说明多线程的一下几个内容: 1.在应用开发中什么时候选择多线程? 2.多线程应该注意些什么? 3.状态转换控制,如何解决死锁? 4.如何设计一个具有可扩展性的多线程处理器? 5.多线程联想:在多主机下的扩展-集群? 6.WEB应用的多线程以及

实现Java多线程的三种方式

1. JAVA多线程实现方式    JAVA多线程实现方式主要有三种: 继承Thread类 实现Runnable接口 使用ExecutorService.Callable.Future实现有返回结果的多线程. 其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的. 2. 继承Thread类实现多线程 继承Thread类的方法尽管被我列为一种多线程实现方式,但 Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread

Java 多线程 三种实现方式

Java多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的. 1.继承Thread类实现多线程继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法.start()方法

Java多线程理解(线程安全)

我们在使用Java多线程时,一定需要考虑到共享,线程安全的相关内容.以下通过几个例子帮助大家来理解多线程时如何运行的,后续通过一篇文章详述解决办法:synchronized. 场景1: 第一次运行结果: [当前线程]----------one=====实例变量的值----x=1 [当前线程]----------two=====实例变量的值----x=2 [当前线程]----------two=====实例变量的值----x=3 [当前线程]----------two=====实例变量的值----

java多线程理解及实现

其实多线程也很好理解,就好比我们坐高铁.飞机过安检一样,过安检的时候一个入口只有一个安检口,而多线程就是为安检开启了多个安检口,话不多说贴代码 线程实现的三种方式: 一.继承Thread类创建线程类 1.定义Thread子类,重写run()方法,把需要做线程操作的类容放入该方法体中. 2.创建Thread子类的实例,在实例中调用线程对象的start()启动线程方法,此方法也是代表线程数量的方法,需要启动多个线程时,只需要调用多次则以. package com.thread; public cla

java多线程理解2

1. 什么时候必须同步?什么叫同步?如何同步? 要跨线程维护正确的可见性,只要在几个线程之间共享非 final 变量,就必须使用 synchronized(或 volatile)以确保一个线程可以看见另一个线程做的更改. 为了在线程之间进行可靠的通信,也为了互斥访问,同步是必须的.这归因于java语言规范的内存 模型 小结:为了防止多个线程并发对同一数据的修改,所以需要同步,否则会造成数据不一致 2. 什么叫原子的(原子操作)? Java原子操作是指:不会被打断地的操作.(就是做到互斥和可见性?

java多线程--实现Runnable接口方式

因为java类只能继承一个类可以实现多个接口的特性,所以一般情况下不推荐使用继承Thread类实现多线程,下面是实现Runnable接口方式的简单多线程代码 package text; /** * 多线程 * @author admin * */ public class Threads { public static void main(String[] args){ Thread_1 t1=new Thread_1(); Thread thread1 =new Thread(t1); thr

Java多线程理解

首先说一下进程和线程的区别 进程:是计算机运用程序实例,拥有独立的内存空间和数据(猜测内存堆应该是作用的进程上),一个进程包含多个子线程,不同进程相互独立: 线程:cpu执行的基本单位,拥有独立的寄存器和栈,同一进程下的线程共享地址&内存空间:线程栈存放方法的栈帧,每次方法执行都会新建栈帧压到栈顶,当线程中某个请求大小超过限制则提示StackOverflowError,当需要存储一个新的栈帧且栈内存不足则抛出OutOfMemoryError:栈帧包含局部变量.返回值.方法引用的常量池(栈帧只能存