以下内容转自http://ifeve.com/creating-and-starting-java-threads/:

Java线程类也是一个object类,它的实例都继承自java.lang.Thread或其子类。 可以用如下方式用java中创建一个线程:

Tread thread = new Thread();

执行该线程可以调用该线程的start()方法:

thread.start();

在上面的例子中,我们并没有为线程编写运行代码,因此调用该方法后线程就终止了。

编写线程运行时执行的代码有两种方式:一种是创建Thread子类的一个实例并重写run方法,第二种是创建类的时候实现Runnable接口。接下来我们会具体讲解这两种方法:

创建Thread的子类

创建Thread子类的一个实例并重写run方法,run方法会在调用start()方法之后被执行。例子如下:

public class MyThread extends Thread {public void run(){System.out.println("MyThread running");}
}

可以用如下方式创建并运行上述Thread子类

MyThread myThread = new MyThread();
myTread.start();

一旦线程启动后start方法就会立即返回,而不会等待到run方法执行完毕才返回。就好像run方法是在另外一个cpu上执行一样。当run方法执行后,将会打印出字符串MyThread running。

你也可以如下创建一个Thread的匿名子类:

Thread thread = new Thread(){public void run(){System.out.println("Thread Running");}
};
thread.start();

当新的线程的run方法执行以后,计算机将会打印出字符串”Thread Running”。

实现Runnable接口

第二种编写线程执行代码的方式是新建一个实现了java.lang.Runnable接口的类的实例,实例中的方法可以被线程调用。下面给出例子:

public class MyRunnable implements Runnable {public void run(){System.out.println("MyRunnable running");}
}

为了使线程能够执行run()方法,需要在Thread类的构造函数中传入MyRunnable的实例对象。示例如下:

Thread thread = new Thread(new MyRunnable());
thread.start();

当线程运行时,它将会调用实现了Runnable接口的run方法。上例中将会打印出”MyRunnable running”。

同样,也可以创建一个实现了Runnable接口的匿名类,如下所示:

Runnable myRunnable = new Runnable(){public void run(){System.out.println("Runnable running");}
}
Thread thread = new Thread(myRunnable);
thread.start();

创建子类还是实现Runnable接口?

对于这两种方式哪种好并没有一个确定的答案,它们都能满足要求。就我个人意见,我更倾向于实现Runnable接口这种方法。因为线程池可以有效的管理实现了Runnable接口的线程,如果线程池满了,新的线程就会排队等候执行,直到线程池空闲出来为止。而如果线程是通过实现Thread子类实现的,这将会复杂一些。

有时我们要同时融合实现Runnable接口和Thread子类两种方式。例如,实现了Thread子类的实例可以执行多个实现了Runnable接口的线程。一个典型的应用就是线程池。

常见错误:调用run()方法而非start()方法

创建并运行一个线程所犯的常见错误是调用线程的run()方法而非start()方法,如下所示:

Thread newThread = new Thread(MyRunnable());
newThread.run();  //should be start();

起初你并不会感觉到有什么不妥,因为run()方法的确如你所愿的被调用了。但是,事实上,run()方法并非是由刚创建的新线程所执行的,而是被创建新线程的当前线程所执行了。也就是被执行上面两行代码的线程所执行的。想要让创建的新线程执行run()方法,必须调用新线程的start方法。

线程名

当创建一个线程的时候,可以给线程起一个名字。它有助于我们区分不同的线程。例如:如果有多个线程写入System.out,我们就能够通过线程名容易的找出是哪个线程正在输出。例子如下:

MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable, "New Thread");
thread.start();
System.out.println(thread.getName());

需要注意的是,因为MyRunnable并非Thread的子类,所以MyRunnable类并没有getName()方法。可以通过以下方式得到当前线程的引用:

Thread.currentThread();

因此,通过如下代码可以得到当前线程的名字:

String threadName = Thread.currentThread().getName();

线程代码举例:

这里是一个小小的例子。首先输出执行main()方法线程名字。这个线程JVM分配的。然后开启10个线程,命名为1~10。每个线程输出自己的名字后就退出。

public class ThreadExample {public static void main(String[] args){System.out.println(Thread.currentThread().getName());for(int i=0; i<10; i++){new Thread("" + i){public void run(){System.out.println("Thread: " + getName() + "running");}}.start();}}
}

这将产生如下所示结果:

需要注意的是,尽管启动线程的顺序是有序的,但是执行的顺序并非是有序的。也就是说,1号线程并不一定是第一个将自己名字输出到控制台的线程。这是因为线程是并行执行而非顺序的。JVM和操作系统一起决定了线程的执行顺序,他和线程的启动顺序并非一定是一致的。

测试工程:https://github.com/easonjim/5_java_example/tree/master/javathread/test1

转载于:https://www.cnblogs.com/EasonJim/p/7012051.html

7、Java并发性和多线程-如何创建并运行线程相关推荐

  1. 【Java并发性和多线程】如何创建并运行java线程

    2019独角兽企业重金招聘Python工程师标准>>> 本文为转载学习 原文链接:http://tutorials.jenkov.com/java-concurrency/creat ...

  2. 并发基础篇(一): Java 并发性和多线程

    说在前面 介绍文章之前,先给出一个多线程的思维导图, 后续的文章就根据思维导图来一步一步的分析java多线程的知识. 一.介绍 在过去单 CPU 时代,单任务在一个时间点只能执行单一程序.之后发展到多 ...

  3. Java并发性和多线程介绍

    作者:Jakob Jenkov 译者:Simon-SZ  校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时 ...

  4. 17、Java并发性和多线程-避免死锁

    以下内容转自http://ifeve.com/deadlock-prevention/: 在有些情况下死锁是可以避免的.本文将展示三种用于避免死锁的技术: 加锁顺序 当多个线程需要相同的一些锁,但是按 ...

  5. Java并发性和多线程介绍、优缺点

    在过去 单核CPU 时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并 不是真正意义上的"同一时间点",而是多个任务 ...

  6. 5、Java并发性和多线程-相同线程

    以下内容转自http://tutorials.jenkov.com/java-concurrency/same-threading.html(使用谷歌翻译): 相同线程(同一线程)是一种并发模型,其中 ...

  7. 21、Java并发性和多线程-Java中的锁

    以下内容转自http://ifeve.com/locks/: 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂.因为锁(以及其它更高级的 ...

  8. 【Java并发性和多线程】Java中的锁

    2019独角兽企业重金招聘Python工程师标准>>> 本文为转载学习 原文链接:http://ifeve.com/locks/ 锁像synchronized同步块一样,是一种线程同 ...

  9. 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...

最新文章

  1. 洗衣机,数据挖掘的物理模型
  2. 【学术相关】博士毕业也会看第一学历吗?
  3. 【学术相关】Github大盘点!2021年最值得推荐的38篇AI论文
  4. Python随机选择一部分训练样本作为测试样本
  5. 一句简单命令重启nginx
  6. 娱乐开源commons-email-1.x包
  7. SQLi LABS Less-29
  8. 【物联网智能网关-08】TinyGUI和WPF汉字显示技术比较
  9. webpack入坑之旅(一)入门安装
  10. Atitit.研发管理软件公司的软资产列表指南
  11. ios12完美深色模式插件_让所有网站开启深色模式,试试这个浏览器插件
  12. Java字符串排序(根据字节及字符长度进行排序)
  13. java如何将字符串转化为日期_java如何将字符串转为日期
  14. 【知识兔课程】跨境电商骗局揭秘及应对策略整理(2021版)
  15. 个人信息安全现状及保护方法
  16. 用python写一个文字版单机斗地主
  17. 电脑读取不U盘,在磁盘管理器中显示“无媒体”解决方法
  18. android小米推送,Android手机端小米推送Demo解析和实现方法
  19. 【精品】居住证、工作居住证、北京户口区别有多大?
  20. python实现3d人物建模_一张图实现3D人脸建模!这是中科院博士生入选ECCV的新研究 | 开源...

热门文章

  1. 华为自带浏览器绕坑大法!
  2. 小程序上让随机的两个点都显示在地图可视区域
  3. STM32CubeMX HAL库串口+DMA数据发送不定长度数据接收
  4. 【BLE】TLSR8258开发记录之12--手机扫描蓝牙显示中文
  5. CTFshow 命令执行 web45
  6. 利用Phtoshop去掉图片中的线性渐变背景
  7. [YTU]_2619 (B 友元类-计算两点间距离)
  8. 2019年财政收支分析_2019年CPI走势预测与分析
  9. matlab画图(复数的直角坐标和极坐标)(-)
  10. mysql报错3534_win7下安装MYSQL报错:MYSQL 服务无法启动的3534问题