java线程之基础学习总结
线程实现的两种方式:
在java中可以有两种方式实现多线程操作,一种是继承Thread类,另外一种是实现Runnable接口。
继承Thread类
Thread类是在java.lang包中定义的
一个类只要继承Thread类,要覆写run()方法。
简单实例
定义MyThread类
- 定义MyThread类
- public class MyThread extends Thread {
- private String name;
- public MyThread(String name) {
- this.name = name;
- }
- public void run() {
- for (int i = 0; i < 5; i++) {
- System.out.println(name + "运行:" + i);
- }
- }
- }
编写TestThread类调用:
- public class TestThread {
- public static void main(String[] args) {
- MyThread myThread1 = new MyThread("singsong1");
- MyThread myThread2 = new MyThread("singsong2");
- myThread1.run();
- myThread2.run();
- }
- }
- 运行结果:
- singsong1运行:0
- singsong1运行:1
- singsong1运行:2
- singsong1运行:3
- singsong1运行:4
- singsong2运行:0
- singsong2运行:1
- singsong2运行:2
- singsong2运行:3
- singsong2运行:4
从结果可以发现,此时的执行非常的有规律,先执行完第一个对象,再执行第二个对象。
把run()方法换成start();一旦调用start()方法,则会通过JVM找到run()方法
Public void start()
使用start()方法启动线程:
- public class TestThread {
- public static void main(String[] args) {
- MyThread myThread1 = new MyThread("singsong1");
- MyThread myThread2 = new MyThread("singsong2");
- myThread1.start();
- myThread2.start();
- }
- }
- 运行结果:
- singsong1运行:0
- singsong1运行:1
- singsong2运行:0
- singsong1运行:2
- singsong2运行:1
- singsong1运行:3
- singsong2运行:2
- singsong1运行:4
- singsong2运行:3
- singsong2运行:4
从运行结果可以知道,程序时交互式的运行。
因为需要用到CPU的资源,所以每次的运行结果基本是都不一样的
不要调用Thread类或Runnable对象的run方法。直接调用run方法,只会执行同一个线程中的任务,而不会启动新线程。应该调用Thread.start()方法。这个方法将创建一个执行run方法的新线程。
Runnable接口的实现
简单实例
- public class RunnableThread implements Runnable {
- private String name;
- public RunnableThread(String name) {
- this.name = name;
- }
- public void run() {
- for (int i = 0; i < 5; i++) {
- System.out.println(name + "运行:" + i);
- }
- }
- }
编写TestThread1调用
- public class TestThread1 {
- public static void main(String[] args) {
- RunnableThread runnableThread1=new RunnableThread("singsong1");
- RunnableThread runnableThread2=new RunnableThread("singsong2");
- Thread thread1= new Thread(runnableThread1);
- Thread thread2= new Thread(runnableThread2);
- thread1.start();
- thread2.start();
- }
- }
- 运行结果:
- singsong1运行:0
- singsong1运行:1
- singsong2运行:0
- singsong2运行:1
- singsong2运行:2
- singsong2运行:3
- singsong2运行:4
- singsong1运行:2
- singsong1运行:3
- singsong1运行:4
Thread类和Runnable接口区别
最大区别是在于资源的共享
如果一个类继承Thread,则资源共享不可共享。而实现Runable接口,能实现资源共享。
例如:
MyThread类
- public class MyThread extends Thread {
- private int ticket = 5;
- private String name;
- public MyThread(String name) {
- this.name = name;
- }
- public void run() {
- for (int i = 0; i < 15; i++) {
- if (ticket > 0) {
- System.out.println(name + "正售出第 " + (ticket--) + "票");
- }
- }
- }
- }
- 调用:
- public class TestThread {
- public static void main(String[] args) {
- MyThread myThread1 = new MyThread("singsong1");
- MyThread myThread2 = new MyThread("singsong2");
- myThread1.start();
- myThread2.start();
- }
- }
- 运行结果:
- singsong1正售出第 5票
- singsong1正售出第 4票
- singsong1正售出第 3票
- singsong1正售出第 2票
- singsong1正售出第 1票
- singsong2正售出第 5票
- singsong2正售出第 4票
- singsong2正售出第 3票
- singsong2正售出第 2票
- singsong2正售出第 1票
重复售出了一次
再来看看Runnable接口是怎么实现资源共享的
RunnableThread类
- public class RunnableThread implements Runnable {
- private int ticket = 5;
- private String name;
- public RunnableThread(String name) {
- this.name = name;
- }
- public void run() {
- for (int i = 10; i > 0; i--) {
- if (ticket > 0) {
- System.out.println(name + "正售出第 " + (ticket--) + "票");
- }
- }
- }
- }
编写TestThread1类调用:
- public class TestThread1 {
- public static void main(String[] args) {
- RunnableThread runnableThread1 = new RunnableThread("singsong1");
- Thread thread1 = new Thread(runnableThread1);
- Thread thread2 = new Thread(runnableThread1);
- thread1.start();
- thread2.start();
- }
- }
- 运行结果:
- singsong1正售出第 5票
- singsong1正售出第 4票
- singsong1正售出第 3票
- singsong1正售出第 2票
- singsong1正售出第 1票
从运行结果可以得出实现Runnable接口的优点。
大家有没有想过Runnable接口为什么能实现资源的共享,而Thread类不能
本人个人理解
首先看如下代码:
- public class TestThread1 {
- public static void main(String[] args) {
- RunnableThread runnableThread1 = new RunnableThread("singsong1");
- RunnableThread runnableThread2 = new RunnableThread("singsong2");
- Thread thread1 = new Thread(runnableThread1);
- Thread thread2 = new Thread(runnableThread2);
- thread1.start();
- thread2.start();
- }
- }
此代码是在TestThread1类的继承上修改的:添加了 RunnableThread runnableThread2 = new RunnableThread("singsong2");
把runnableThread1换成runnableThread2
现在我们在运行程序看看结果:
- singsong1正售出第 5票
- singsong1正售出第 4票
- singsong1正售出第 3票
- singsong1正售出第 2票
- singsong1正售出第 1票
- singsong2正售出第 5票
- singsong2正售出第 4票
- singsong2正售出第 3票
- singsong2正售出第 2票
- singsong2正售出第 1票
从结果可以知道也重复了一次。
总结一下:也是就说Runnable接口能实现资源的共享是因为用同一个实现Runnable接口的子类来创建不同的线程,去执行同一个任务。而Thread却没有这种机制。
转载于:https://blog.51cto.com/singsong/1163248