javajava 多线程区别Thread和Runnable的区别

Java线程中继承thread类与实现Runnable接口的区别 - 推酷
Java线程中继承thread类与实现Runnable接口的区别
Java中线程的创建有两种方式:
1. && 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中
通过实现Runnable接口,实例化Thread类
在实际应用中,我们经常用到多线程,如车站的售票系统,车站的各个售票口相当于各个线程。当我们做这个系统的时候可能会想到两种方式来实现,继承Thread类或实现Runnable接口,现在看一下这两种方式实现的两种结果。
Java代码&&
package com.&&
class MyThread& extends Thread{&&
private int ticket&=& 10 ;&&
private String&&&
public MyThread(String&name){&&
this .name&=&&
public void run(){&&
for ( int i&= 0 ;i& 500 ;i++){&&
if ( this .ticket& 0 ){&&
System.out.println( this .name+ &卖票----&& +( this .ticket--));&&
public class ThreadDemo&{&&
public static void main(String[]&args)&{&&
MyThread&mt1=& new MyThread( &一号窗口& );&&
MyThread&mt2=& new MyThread( &二号窗口& );&&
MyThread&mt3=& new MyThread( &三号窗口& );&&
mt1.start();&&
mt2.start();&&
mt3.start();&&
运行结果如下:
Java代码&&
一号窗口卖票----& 10
一号窗口卖票----& 9
二号窗口卖票----& 10
一号窗口卖票----& 8
一号窗口卖票----& 7
一号窗口卖票----& 6
三号窗口卖票----& 10
一号窗口卖票----& 5
一号窗口卖票----& 4
一号窗口卖票----& 3
一号窗口卖票----& 2
一号窗口卖票----& 1
二号窗口卖票----& 9
二号窗口卖票----& 8
三号窗口卖票----& 9
三号窗口卖票----& 8
三号窗口卖票----& 7
三号窗口卖票----& 6
三号窗口卖票----& 5
三号窗口卖票----& 4
三号窗口卖票----& 3
三号窗口卖票----& 2
三号窗口卖票----& 1
二号窗口卖票----& 7
二号窗口卖票----& 6
二号窗口卖票----& 5
二号窗口卖票----& 4
二号窗口卖票----& 3
二号窗口卖票----& 2
二号窗口卖票----& 1
通过实现Runnable接口的代码如下:
Java代码&&
package com.&&
class MyThread1& implements Runnable{&&
private int ticket&= 10 ;&&
private String&&&
public void run(){&&
for ( int i&= 0 ;i& 500 ;i++){&&
if ( this .ticket& 0 ){&&
System.out.println(Thread.currentThread().getName()+ &卖票----&& +( this .ticket--));&&
public class RunnableDemo&{&&
public static void main(String[]&args)&{&&
//&TODO&Auto-generated&method&stub
//设计三个线程
MyThread1&mt&=& new MyThread1();&&
Thread&t1&=& new Thread(mt, &一号窗口& );&&
Thread&t2&=& new Thread(mt, &二号窗口& );&&
Thread&t3&=& new Thread(mt, &三号窗口& );&&
//&&&&&&&&&MyThread1&mt2&=&new&MyThread1();
//&&&&&&&&&MyThread1&mt3&=&new&MyThread1();
t1.start();&&
t2.start();&&
t3.start();&&
运行结果如下:
Java代码&&
一号窗口卖票----& 10
三号窗口卖票----& 9
三号窗口卖票----& 7
三号窗口卖票----& 5
三号窗口卖票----& 4
三号窗口卖票----& 3
三号窗口卖票----& 2
三号窗口卖票----& 1
一号窗口卖票----& 8
二号窗口卖票----& 6
为什么会出现这种结果呐。我们不妨做个比喻,其实刚的程序,
继承Thread类的,我们相当于拿出三件事即三个卖票10张的任务分别分给三个窗口,他们各做各的事各卖各的票各完成各的任务,因为MyThread继承Thread类,所以在new MyThread的时候在创建三个对象的同时创建了三个线程;
实现Runnable的,&相当于是拿出一个卖票10张得任务给三个人去共同完成,new MyThread相当于创建一个任务,然后实例化三个Thread,创建三个线程即安排三个窗口去执行。
用图表示如下:
在我们刚接触的时候可能会迷糊继承Thread类和实现Runnable接口实现多线程,其实在接触后我们会发现这完全是两个不同的实现多线程,一个是多个线程分别完成自己的任务,一个是多个线程共同完成一个任务。
其实在实现一个任务用多个线程来做也可以用继承Thread类来实现只是比较麻烦,一般我们用实现Runnable接口来实现,简洁明了。
大多数情况下,如果只想重写&run()&方法,而不重写其他&Thread&方法,那么应使用&Runnable&接口。这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类(Thread)创建子类。
原文链接:
免责申明: 架构说任何转载的文章都会明确标注原文链接。如有侵权,请与本站联系。 转载说明: 架构说原创文章转载时请务必注明文章作者、链接和来源。
扫描关注“架构说”微信公众号,微信公众号内可加入微信和QQ群,让架构师带你飞︿( ̄︶ ̄)︿。架构说,让架构更简单。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Java多线程
不理解继承Thread和实现Runable的区别 求指教
//定义了一个线程
启动三个线程 去跑
package com.test.
public class ThreadTest extends Thread{
int ticket =10;
public void run() {
for(int i =0;i&20;i++){
if(this.ticket&0){
System.out.println(Thread.currentThread().getName()+"买票"+this.ticket--);
//定义了一个Runable 也是同样的代码
package com.test.
public class RunableTest implements Runnable{
int ticket =10;
public void run() {
for (int i = 0; i & 20; i++) {
if(this.ticket&0){
System.out.println(Thread.currentThread().getName()+"卖出"+this.ticket--);
//定义一个main方法
package com.test.
public class Test {
public static void main(String[] args) throws InterruptedException {
ThreadTest t1 = new ThreadTest();
ThreadTest t2 = new ThreadTest();
ThreadTest t3 = new ThreadTest();
t1.start();
t2.start();
t3.start();
Thread.sleep(1000);
System.out.println("====================");
RunableTest r1 = new RunableTest();
new Thread(r1).start();
new Thread(r1).start();
new Thread(r1).start();
//控制台打印这样的结果
我是想让他打印当前线程 和ticket的数量 但是runable接口只有一个线程再跑 我明明start()了三个 不理解 这样的结果
Thread-0买票10
Thread-0买票9
Thread-0买票8
Thread-0买票7
Thread-0买票6
Thread-0买票5
Thread-0买票4
Thread-0买票3
Thread-0买票2
Thread-0买票1
Thread-2买票10
Thread-2买票9
Thread-2买票8
Thread-2买票7
Thread-2买票6
Thread-2买票5
Thread-2买票4
Thread-2买票3
Thread-2买票2
Thread-2买票1
Thread-1买票10
Thread-1买票9
Thread-1买票8
Thread-1买票7
Thread-1买票6
Thread-1买票5
Thread-1买票4
Thread-1买票3
Thread-1买票2
Thread-1买票1
====================
Thread-4卖出10
Thread-4卖出9
Thread-4卖出8
Thread-4卖出7
Thread-4卖出6
Thread-4卖出5
Thread-4卖出4
Thread-4卖出3
Thread-4卖出2
Thread-4卖出1
Runnable是Thread的接口,在大多数情况下“推荐用接口的方式”生成线程,因为接口可以实现多继承,况且Runnable只有一个run方法,很适合继承。 Thread本身就是实现了Runable接口
在使用Thread的时候只需要new一个实例出来,调用start()方法即可以启动一个线程。
Thread Test = new Thread();
Test.start();
在使用Runnable的时候需要先new一个继承Runnable的实例,之后用子类Thread调用。
Test impelements Runnable
Test t = new Test();
Thread test = new Thread(t);
继承了Thread类 那么实例化该子线程类后 你只能调用一次 start&
而实现了 Runnable 接口 这个对象 就可以使用无数次
Test impelements Runnable
Test t = new Test();
你调用一次new Thread(t).start();接着在写new Thread(t).start& 这样没有任何问题;
--- 共有 2 条评论 ---
: 呵呵 小意思
Thread才是线程,Runnable只是表示一个被封装的运行内容。实际上一直觉得Java让Thread实现Runnable接口是个错误
--- 共有 1 条评论 ---
一个是继承,一个是实现接口。
1.继承直接new然后start()
2.接口必须在加载进入new Thread(Object implements Runnable),然后调用start().
--- 共有 1 条评论 ---
Runnable都可以。上边说的很清楚了,给你补充下
记得jdk1.5并发库里面就有因为继承Thread而导致的,内存泄露.改成接口就没问题。不过那是过去了。这个bug记得是jdk1.6的时候修正了。
--- 共有 1 条评论 ---
其实你的代码已经体现出使用Runnable的第一个好处:使用实现Runnable的方式可以让多个Thread共享资源,而直接继承Thread想做到资源共享就没那么方便了。
通过以上的内容也可以体现出Runnable比Thread更据灵活性,这也是为什么Java提倡使用接口,这就是第二个好处了。
--- 共有 1 条评论 ---> java 创设线程的三种方法Callable,Runnable,Thread比较及用法
java 创设线程的三种方法Callable,Runnable,Thread比较及用法
hnluoyang & &
发布时间: & &
浏览:44 & &
回复:0 & &
悬赏:0.0希赛币
java 创建线程的三种方法Callable,Runnable,Thread比较及用法  编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互。一般有三种方法,Thread,Runnable,Callable.
  Runnable和Callable的区别是,
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
  1、通过实现Runnable接口来创建Thread线程:
  步骤1:创建实现Runnable接口的类:
class SomeRunnable implements Runnable
&&& public void run()
&&&&& //do something here
  步骤2:创建一个类对象:
  Runnable oneRunnable = new SomeRunnable();
  步骤3:由Runnable创建一个Thread对象:
  Thread oneThread = new Thread(oneRunnable);
  步骤4:启动线程:
  oneThread.start();
  至此,一个线程就创建完成了。
  注释:线程的执行流程很简单,当执行代码oneThread.start();时,就会执行oneRunnable对象中的void run();方法,
  该方法执行完成后,线程就消亡了。
  2、与方法1类似,通过实现Callable接口来创建Thread线程:其中,Callable接口(也只有一个方法)定义如下:
  public interface Callable&V$>$&
&&& V call() throws E&&
步骤1:创建实现Callable接口的类SomeCallable&Integer&(略);
  步骤2:创建一个类对象:
  Callable&Integer& oneCallable = new SomeCallable&Integer&();
  步骤3:由Callable&Integer&创建一个FutureTask&Integer&对象:
  FutureTask&Integer& oneTask = new FutureTask&Integer&(oneCallable);
  注释:FutureTask&Integer&是一个包装器,它通过接受Callable&Integer&来创建,它同时实现了Future和Runnable接口。
步骤4:由FutureTask&Integer&创建一个Thread对象:
  Thread oneThread = new Thread(oneTask);
  步骤5:启动线程:
  oneThread.start();
  至此,一个线程就创建完成了。
  3、通过继承Thread类来创建一个线程:
  步骤1:定义一个继承Thread类的子类:
class SomeThead extends Thraad
&&& public void run()
&&&& //do something here
  步骤2:构造子类的一个对象:
  SomeThread oneThread = new SomeThread();
  步骤3:启动线程:
  oneThread.start();
  至此,一个线程就创建完成了。
  注释:这种创建线程的方法不够好,主要是因为其涉及运行机制问题,影响程序性能。
  转自:
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&java多线程:Thread类介绍,实现方式,示例 - 为程序员服务
为程序员服务
java多线程:Thread类介绍,实现方式,示例
java是一个多线程的编程语言,就是说在java的应用中可以并行的执行多个线程,每个线程可以执行不同的操作。在单cpu的机器上多线程会分享cpu时间,而在多线程的机器上不同线程可以使用不同的CPU。
java线程的生命周期
java线程在他的生命周期内有几种不同的状态:线程初始化,启动,运行和死亡。
上图所示的状态解释如下:
new&是指线程被初始化,但是还没有调用其start方法,还没有开始执行
runnable&调用线程的start方法之后,线程开始执行其任务,这时候线程是运行状态
waiting&有时候线程需要等待另外一个线程执行完毕之后再执行,这时候线程处于等待状态,处于等待状态的线程需要其他线程notify之后才能恢复到运行状态
timed waiting&运行中的线程可以进入到定时等待的状态,这时候线程间隔指定的时间间隔之后就会恢复到运行状态
terminated&当线程任务执行完毕或者被abort的时候线程处于终止状态
java线程的优先级
每一个java线程都有一个优先级,操作系统可以通过线程的优先级决定决定将cpu分配给哪个线程。优先级越高的线程越可能得到cpu资源。
java线程优先级的值在1-10之间,1是常量MIN_PRIORITY,10是常量MAX_PRIORITY 。默认情况下java的线程的优先级是NORM_PRIORITY 即5.
高优先级的线程通常更重要,更有可能获得cpu时间资源,但是并不能保证绝对可以获得cpu。
java多线程实现的两种方式
1. 使用Runnable接口实现多线程
使用Runnable接口实现多线程需要两个步骤,首先实现Runnable接口类,然后声明Thread实例,调用thread实例的start方法,开始执行。
如下代码示例:
package cn.outofmemory.java.
public class RunTask implements Runnable {
public void run() {
for (int i=0;i&10;i++) {
System.out.println("hello counter " + i);
Thread.sleep(20);
} catch (InterruptedException e) {
package cn.outofmemory.java.
public class App {
public static void main(String[] args) {
for (int i = 0; i & 2; i++) {
Runnable task = new RunTask();
Thread t = new Thread(task);
t.start();
&上面的RunTask类实现了Runnable的接口,App类的main方法for循环生成Runnable示例,并将其传递给Thread示例的构造函数中,然后调用start方法启动线程。
上面程序将输出:
hello counter 0
hello counter 0
hello counter 1
hello counter 1
hello counter 2
hello counter 2
hello counter 3
hello counter 3
hello counter 4
hello counter 4
hello counter 5
hello counter 5
hello counter 6
hello counter 6
hello counter 7
hello counter 7
hello counter 8
hello counter 8
hello counter 9
hello counter 9
&可以看到两个线程在并行的执行。
2. 从Thread类继承实现java的多线程
从java的Thread类继承实现多线程,也是实现其run方法,然后声明实例,并调用实例的start方法启动线程。
代码示例如下:
package cn.outofmemory.java.
public class SimpleThread extends Thread {
public void run() {
for (int i=0;i&10;i++) {
System.out.println("thread " + this.getId() + " print out " + i);
Thread.sleep(0);
} catch (InterruptedException e) {
package cn.outofmemory.java.
public class App {
public static void main(String[] args) {
for (int i = 0; i & 2; i++) {
Thread t = new SimpleThread();
t.start();
SimpleThead类从Thread类继承,并重写了run方法。 在App类的main方法中for循环new了两个SimpleThread的实例,并调用其start方法。
程序输出类似于:
thread 12 print out 0
thread 11 print out 0
thread 12 print out 1
thread 12 print out 2
thread 12 print out 3
thread 12 print out 4
thread 12 print out 5
thread 12 print out 6
thread 11 print out 1
thread 11 print out 2
thread 12 print out 7
thread 11 print out 3
thread 12 print out 8
thread 12 print out 9
thread 11 print out 4
thread 11 print out 5
thread 11 print out 6
thread 11 print out 7
thread 11 print out 8
thread 11 print out 9
java Thread类的主要方法介绍&
Thread的实例方法:
方法定义方法说明
public void start()
最常用的方法,顾名思义启动线程,即开始执行线程的run方法
public void run()
如果线程重写了run方法,那么执行重写的方法,否则执行线程的Runnable接口中定义的run方法
public final void setName(String)
设置线程的名称
public final void setPriority(int)
设置线程的优先级(范围在1-10包含1,10)
public final void setDeamon(boolean)
设置线程是否是后台线程
public final void join(long)
在另外一个线程中调用当前线程的join方法,会导致当前线程阻塞,直到另一线程执行完毕,或者超过参数指定毫秒数
public void interrupt()
public final boolean isAlive()
线程是否处于存活状态,线程在启动和结束之前都处于存活状态
Thread类的常用静态方法:
方法定义方法说明
public static void yield()
使当前运行线程相同优先级的线程获得执行机会,类似sleep,但是只会将cpu让给相同优先级的线程
public static void sleep(long)
使当前线程休眠指定毫秒的时间
public static boolean holdsLock(Object x)
判断当前线程是否拥有对象的锁
public static Thread currentThread()
获得当前线程实例
public static void dumpStack()
打印当前线程的执行堆栈,这对多线程程序的调试很有帮助
java线程示例1: 如何使用interupt方法中断线程
public class GeneralInterrupt extends Object&
implements Runnable {
& &public void run() {
& & & try {
& & & & &System.out.println("in run() -&about to work2()");
& & & & &work2();
& & & & &System.out.println("in run() -&back from &work2()");
& & & catch (InterruptedException x) {
& & & & &System.out.println("in run() -& interrupted in work2()");
& & & System.out.println("in run() -&doing stuff after nap");
& & & System.out.println("in run() -&leaving normally");
& &public void work2() throws InterruptedException {
& & & while (true) {
& & & & &if (Thread.currentThread().isInterrupted()) {
& & & & & & System.out.println("C isInterrupted()="
& & & & & & + Thread.currentThread().isInterrupted());
& & & & & & Thread.sleep(2000);
& & & & & & System.out.println("D isInterrupted()="
& & & & & & + Thread.currentThread().isInterrupted());
& & & & &}
& &public void work() throws InterruptedException {
& & & while (true) {
& & & & &for (int i = 0; i & 100000; i++) {
& & & & & & int j = i * 2;
& & & & &}
& & & & &System.out.println("A isInterrupted()="
& & & & &+ Thread.currentThread().isInterrupted());
& & & & &if (Thread.interrupted()) {
& & & & & & System.out.println("B isInterrupted()="
& & & & & & + Thread.currentThread().isInterrupted());
& & & & & & throw new InterruptedException();
& & & & &}
& &public static void main(String[] args) {
& & & GeneralInterrupt si = new GeneralInterrupt();
& & & Thread t = new Thread(si);
& & & t.start();
& & & try {
& & & & &Thread.sleep(2000);
& & & catch (InterruptedException x) {
& & & System.out.println("in main() -&
& & & interrupting other thread");
& & & t.interrupt();
& & & System.out.println("in main() - leaving");
以上程序输出:
in run() - about to work2()
in main() - interrupting other thread
in main() - leaving
C isInterrupted()=true
in run() - interrupted in work2()
java线程示例2:后台线程示例
package cn.outofmemory.java.
public class DaemonThread implements Runnable {
public void run() {
System.out.println("entering run()");
System.out.println("in run(): currentThread() is"
+ Thread.currentThread());
while (true) {
Thread.sleep(500);
} catch (InterruptedException x) {
System.out.println("in run(): woke up again");
} finally {
System.out.println("leaving run()");
public static void main(String[] args) {
System.out.println("entering main()");
Thread t = new Thread(new DaemonThread());
t.setDaemon(true);
t.start();
Thread.sleep(3000);
} catch (InterruptedException x) {
System.out.println("leaving main()");
程序运行将输出如下内容:
entering main()
entering run()
in run(): currentThread() isThread[Thread-0,5,main]
in run(): woke up again
in run(): woke up again
in run(): woke up again
in run(): woke up again
in run(): woke up again
leaving main()
in run(): woke up again
java多线程还有很多高级的内容,本文只是阐述了Thread类的基础用法。
推荐阅读:
相关聚客文章Runnable,Thread实现多线程以及Runnable的同步资源共享_Java教程_动态网站制作指南
Runnable,Thread实现多线程以及Runnable的同步资源共享
来源:人气:360
& & &实现多线程有两种方式
& & &继承Thread类,重写run()方法,如以下例子
& & &class MyThread extends Thread{
& & & & &public void run(){
& & & & &//
& & & & &}
& &class Main{
& & & & public void main(String[] args){
& & & & MyThread thread=new Mythread();
& & & & thread.start();
& & 利用runnable接口实现,但是若只是定义了Runnable对象,如
public class Myobject
public static void main(String[] args)
//System.out.intln("主线程" + Thread.currentThread().getName());
Runnable myRunnable = new Runnable()
public void run()
System.out.println(Thread.currentThread().getName());
  Runnable对象必须依赖一个Thread类才能真正意义上说是另外开辟了一个线程,不然是默认在主线程中的,在Android更新UI有这种应用,利用runOnUiThread(runnable)来在主线程的某一块调用Runnable的run方法,此时并没有开辟另外的线程,而是在主线程中执行的,这一点应该分清楚。
真正意义上的开辟另外的线程看下面,需要Thread.start()来调用Runnable接口的run方法 & &
& & class MyThread implements Runnable{
& & & & &public void run(){
& & & & &//
& & & & &}
& &class Main{
& & & &public static void main(String[] args){
& & & &MyThread thread=new MyThread();//实例化runnable对象
& & & &Thread thread1=new Thread(thread);//通过Thread实例化runnable对象
& & & &thread1.start();//利用Thread线程类启动Runnable接口的run方法
(二)在利用Runnable进行多线程时,则有时候需要资源共享
当分配一个任务给多人时,假如要实现资源共享那么就用到
synchronized (this){
同步代码块
那我们就举个买票的例子
定义个ThreadTicket类
package MyT
public class ThreadTicket
public static void main(String[] args)
MyThread myThread1=new MyThread();
Thread t1 = new Thread(myThread1);//一窗口
Thread t2 = new Thread(myThread1);//二窗口
Thread t3 = new Thread(myThread1);//三窗口
t1.start();
t2.start();
t3.start();
  此时的实现MyThread接口类
package MyT
public class MyThread implements Runnable
private int ticket = 10;
public void run()
//synchronized (this)
for (int i = 0; i & 10; i++)
Thread.sleep(500);
} catch (InterruptedException e)
// TODO 自动生成的 catch 块
e.printStackTrace();
if (ticket & 0)
System.out.println("车票 :" + ticket--);
  由MyThread类可以得出此时的购票总数是10张票,分三个窗口买,那么此时就需要三个窗口共享票源,当没票时就不再进行售票
当不添加synchronized关键字时,此时显示的结果为
可以看到此时的结果是杂乱无章,完全没有达到资源共享
此时应该利用synchronized(this)
同步代码块来实现资源共享
就是将MyThread的synchronized部分注释解除,此时的结果为
成功实现了资源共享的目的。
Runnable的很大的优点就在于资源共享。
优质网站模板

我要回帖

更多关于 java进程和线程的区别 的文章

 

随机推荐