Java创建线程的两种方式

mac2024-04-06  35

参考:

Java创建线程的两种方式

导航:

实现Runnable方法

继承Thread类

start()方法和run()方法区别

比较

实现接口的方式比继承类的方式更灵活, 也能减少程序之间的耦合度,面向接口编程也是设计模式6大原则的核心

implements Runnable

public class RunnalbleTest2 implements Runnable { private int threadCnt = 10; @Override public void run() { while (true) { if (threadCnt > 0) { System.out.println(Thread.currentThread().getName() + " 剩余个数 " + threadCnt); threadCnt--; try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } else { break; } } } public static void main(String[] args) { RunnalbleTest2 runnalbleTest2 = new RunnalbleTest2(); new Thread(runnalbleTest2).start(); new Thread(runnalbleTest2).start(); new Thread(runnalbleTest2).start(); new Thread(runnalbleTest2).start(); } } //Thread-1 剩余个数 10 //Thread-2 剩余个数 9 //Thread-0 剩余个数 8 //Thread-3 剩余个数 7 //Thread-1 剩余个数 6 //Thread-0 剩余个数 5 //Thread-2 剩余个数 4 //Thread-3 剩余个数 3 //Thread-1 剩余个数 2 //Thread-0 剩余个数 1

可以看出该实例中虽然是2个线程,但操作的threadCnt却是一个,实现了资源共享。

extends Thread

public class ThreadTest2 extends Thread { private int threadCnt = 10; @Override public void run() { while (true) { if (threadCnt > 0) { System.out.println(Thread.currentThread().getName() + " 剩余个数 " + threadCnt); threadCnt--; try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } else { break; } } } public static void main(String[] args) { new ThreadTest2().start(); new ThreadTest2().start(); } } //Thread-0 剩余个数 10 //Thread-1 剩余个数 10 //Thread-0 剩余个数 9 //Thread-1 剩余个数 9 //Thread-0 剩余个数 8 //Thread-1 剩余个数 8 //Thread-0 剩余个数 7 //Thread-1 剩余个数 7 //Thread-0 剩余个数 6 //Thread-1 剩余个数 6 //Thread-0 剩余个数 5 //Thread-1 剩余个数 5 //Thread-0 剩余个数 4 //Thread-0 剩余个数 3 //Thread-1 剩余个数 4 //Thread-0 剩余个数 2 //Thread-1 剩余个数 3 //Thread-0 剩余个数 1 //Thread-1 剩余个数 2 //Thread-1 剩余个数 1

start()方法和run()方法区别

import java.text.SimpleDateFormat; public class TestNoStart { static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.sss"); public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread() { @Override public void run() { pong(1); try { Thread.sleep(7000); } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread t2 = new Thread() { @Override public void run() { pong(2); try { Thread.sleep(7000); } catch (InterruptedException e) { e.printStackTrace(); } } }; t1.start(); t2.start(); // t1.run(); // t2.run(); System.out.println(getTime() + " ping~~~~"); } static void pong(int i) { System.out.println(getTime() + " pong~" + i); } static String getTime() { return dateFormat.format(System.currentTimeMillis()); } } //run //2019-10-31 11:15:49.049 pong~1 //2019-10-31 11:15:56.056 pong~2 //2019-10-31 11:16:03.003 ping~~~~ //start //2019-10-31 11:16:27.027 ping~~~~ //2019-10-31 11:16:27.027 pong~2 //2019-10-31 11:16:27.027 pong~1

start()方法和run()方法区别:

涉及到线程的几个状态

新建状态:使用 new 关键字和 Thread 类(或其子类)建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。

就绪状态:当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。

运行状态:如果就绪状态的线程获取到 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。

只有调用了start()方法,才会表现出多线程的特性, 不同线程的run()方法里面的代码交替执行。 如果只是调用run()方法,那么代码还是同步执行的,必须等待一个线程的run()方法里面的代码全部执行完毕之后, 另外一个线程才可以执行其run()方法里面的代码。

最新回复(0)