目
run()和start()方法哪个是启动线程的方法?线程能不能多次启动?为什么要重写run方法?
1.有的时候我们给线程设置了指定的优先级,但是该线程并不是按照优先级高的线程执行,那是为什么呢?
多线程小编已经在上一篇文章中详细介绍过了!接下来就看看多线程如何创建以及其中的方法等等!

由于线程是依赖进程而存在的,所以我们应该先创建一个进程(JVM)出来。而进程是由系统创建的,所以我们应该 去调用系统功能创建一个进程。 但是Java是不能直接调用系统的,所以我们没有办法直接实现多线程程序。但是, Java可以去调用C/C++写好的程序来实现多线程程序。由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西,最后 提供一些类供我们使用, 就可以 实现多线程程序 了。
那么问题来啦!接招吧~~~~
可不要觉得这都so easy!也会有朋友不懂这些问题的!首先启动线程使用的不是run方法,而是 start方法. 直接用线程.run()是无法成功启动线程的!咱们创建好线程后便调用start方法启动线程,随后由Java 虚拟机调用该线程的 run 方法. 还有针对 同一个线程对象不要重复调用 start(). 注意是线程对象!同一个线程不同线程对象的话是可以多次启动的!那么为什么非要重写run方法?如果我们不重写Thread类中的run方法,run()则将执行Thread类自身原有的方法,并且由于Thread类run()的实现为空,因此不会获得任何输出。如果你想 run方法里面实现你想实现的功能, 拿当然就得重写啦!
- public class MyThread extends Thread { //继承Thread类
- //重写run方法
- @Override
- public void run() {
- System.out.println("具体需要实现的功能!");
- }
- }
-
-
- public class MyTest {
- public static void main(String[] args) {
- MyThread th = new MyThread(); //创建对象
- //th.run(); //这样不是开启了线程,你这是创建了一个对象,调用了run方法,没有新的线程开启。
- th.start(); //调用start()方法启动线程
-
- // th.start(); 同一个线程对象不要重复调用 start()
- MyThread th2 = new MyThread(); //新的线程对象
- th2.start();
- }
- }
这个方法的 优点在于扩展性强, 实现一个接口的同时还可以再去继承其他类. 可以避免由于Java单继承带来的局限性.
- public class MyRunnable implements Runnable { //实现Runnable 接口
- //重写run方法
- @Override
- public void run() {
- System.out.println("具体实现的功能!");
- }
- }
-
-
- public class MyTest {
- public static void main(String[] args) {
- MyRunnable myRunnable = new MyRunnable(); //创建对象
- Thread th = new Thread(myRunnable); //new Thread 把这个类的对象作为参数,传过来
- th.start(); //调用start()方法启动
-
- }
- }
注意: 实现 Callable 接口相较于实现 Runnable 接口的方式, 方法可以有返回值,并且可以抛出异常. 执行 Callable 方式, 需要 FutureTask 实现类的支持, 用于接收运算结果. FutureTask 是 Future 接口的实现类.并且Runnable 他的run方法,没有返回值,也不能抛出异常. 而Callable 他的call方法,有返回值,还可以抛出异常. 如果说咱们想拿到线程执行完后返回的结果,就可以用 Callable 任务.也就是用第三种方式来创建线程哈!
- public class MyCallable implements Callable
{ //实现Callable接口 - private int num;
-
- public MyCallable(int num) {
-
- this.num = num;
- }
-
- //call方法也是线程将来执行的方法
- @Override
- public Integer call() throws Exception {
- int sum = 0;
- for (int i = 1; i <= num; i++) {
- sum += i;
- }
- return sum;
- }
- }
-
-
-
- public class MyTest {
- public static void main(String[] args) throws ExecutionException, InterruptedException {
-
- MyCallable myCallable = new MyCallable(100);
- //可使用 FutureTask 包装 Callable 或 Runnable 对象。因为 FutureTask 实现了 Runnable,所以可将 FutureTask 提交给 Executor 执行。
- FutureTask
futureTask = new FutureTask<>(myCallable); //创建一个FutureTask类将Callable接口的子类对象作为参数传进去 -
- Thread th = new Thread(futureTask); //创建Thread类,将FutureTask对象作为参数传进去
- th.start(); //开启线程
-
- Integer integer = futureTask.get();
- System.out.println(integer);
-
- //获取子线程执行完之后的结果
- Integer integer1 = futureTask2.get();
- System.out.println(integer1);
-
- }
- }

- public class MyTest {
- public static void main(String[] args) throws InterruptedException {
- System.out.println("主线程中代码AAA");
- Thread thObj = Thread.currentThread(); //currentThread();获取当前执行的线程对象
- thObj.setName("主线程"); //设置线程名称
- System.out.println(thObj.getName()); //获取线程名称
- //开启一个子线程
- MyThread th1 = new MyThread();
- th1.setName("范冰冰");
-
- th1.setPriority(Thread.MAX_PRIORITY); //设置线程的优先级
- int priority = th1.getPriority(); //获取线程的优先级
- System.out.println("th1的优先级:" + priority);
- th1.start();
-
- //再开启一个子线程
- MyThread th2 = new MyThread();
- th2.setName("刘亦菲");
- th2.setPriority(Thread.MIN_PRIORITY);
- int priority1 = th2.getPriority();
- System.out.println("th2的优先级:" + priority1);
- th2.start();
-
- th2.stop(); //强制停止线程
-
- //让当前线程休眠
- Thread.sleep(1000 * 3); //休眠之后的代码不再执行
-
- }
- }
-
-
- public class MyThread extends Thread {
- public MyThread() {
-
- }
-
- @Override
- public void run() {
-
- for (int i = 0; i < 100; i++) {
- System.out.println(Thread.currentThread().getName() + "-子线程执行的代码:" + i);
- }
- }
- }
-
加入线程join()方法演示
- public class MyTest {
- public static void main(String[] args) throws InterruptedException {
- MyThread th1 = new MyThread("刘备");
- MyThread th2 = new MyThread("关羽");
- MyThread th3 = new MyThread("张飞");
- th1.start();
- th1.join();
- th2.start();
- th2.join();
- th3.start();
- th3.join();
-
- //join()在线程开启之后,调用,可以把多个线程并发执行,变为串行。
-
- }
- }
-
-
- public class MyThread extends Thread {
- public MyThread() {
- }
- public MyThread(String name) {
- super(name);
- }
- @Override
- public void run() {
- for (int i = 0; i < 100; i++) {
- System.out.println(this.getName() + "-子线程执行的代码:" + i);
- }
- }
- }
-
-
礼让线程yield()方法演示
- public class MyTest {
- public static void main(String[] args) throws InterruptedException {
- MyThread th1 = new MyThread("刘备");
- MyThread th2 = new MyThread("关羽");
- th1.start();
- th2.start();
- }
- }
-
-
- public class MyThread extends Thread {
- public MyThread() {
- }
-
- public MyThread(String name) {
- super(name);
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 100; i++) {
- System.out.println(this.getName() + "-子线程执行的代码:" + i);
- Thread.yield(); //线程礼让
- }
- }
- }
设置守护线程案例演示
- public class MyTest {
- public static void main(String[] args) throws InterruptedException {
- Thread main = Thread.currentThread();
- main.setName("刘备");
- for (int i = 0; i < 10; i++) {
- System.out.println(main.getName() + "i");
- }
- MyThread th2 = new MyThread("关羽");
- MyThread th3 = new MyThread("张飞");
- //设置守护线程 当用户线程死亡后,守护线程也要立即死亡
- th2.setDaemon(true);
- th2.start();
- //设置守护线程
- th3.setDaemon(true);
- th3.start();
-
- }
- }
-
-
- public class MyThread extends Thread {
- public MyThread() {
- }
-
- public MyThread(String name) {
- super(name);
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 1000; i++) {
- System.out.println(this.getName() + "-子线程执行的代码:" + i);
- }
- }
- }
清楚阻塞状态interrupt()演示
- public class MyTest {
- public static void main(String[] args) throws InterruptedException {
- MyThread th = new MyThread("线程A");
- th.start();
- th.interrupt(); //清除线程阻塞的状态
- }
- }
-
-
-
- public class MyThread extends Thread {
- public MyThread() {
- }
-
- public MyThread(String name) {
- super(name);
- }
-
- @Override
- public void run() {
- try {
- Thread.sleep(5 * 1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- for (int i = 0; i < 1000; i++) {
- System.out.println(this.getName() + "-子线程执行的代码:" + i);
- }
- }
- }

因为线程的优先级的大小 仅仅表示这个线程被CPU执行的概率增大 了.但是我们都知道多线程 具有随机性, 所以有的时候一两次的运行说明不了问题的!
如果事先并没有给线程设置优先级,而java采用的又是抢占式调度模型,那么这个线程肯定存在一个默认的优先级.通过getPriority()方法获取线程的优先级.就可以发现线程的 默认优先级是5. 其次线程的 优先级范围是 1---10. 这就不用说啦,肯定是10 的优先级最大咯!
按照我们的想法,这个礼让应该是一个线程执行一次,但是通过测试就发现该效果并不明显.礼让线程是要暂停当前正在执行的线程,这个 暂停的时间是相当短 的,如果在这个线程暂停完毕以后,其他的线程还没有抢占到CPU的执行权,那么这个时候这个线程就会再次和其他线程抢占CPU的执行权.
用户线程和守护线程都是线程,区别是Java虚拟机在所有用户线程dead后,程序就会结束.而不管是否还有守护线程还在运行,若守护线程还在运行,也会马上结束. 也就是说 当用户线程dead后,守护线程也要立即dead. 由两者的区别及dead时间点可知,守护线程不适合用于输入输出或计算等操作,因为用户线程执行完毕,程序就dead了, 适用于辅助用户线程的场景, 如JVM的垃圾回收,内存管理都是守护线程,还有就是在做数据库应用的时候,使用的数据库连接池,连接池本身也包含着很多后台线程,监听连接个数、超时时间、状态等.
![]()
(小编也在努力学习更多哟!以后再慢慢分享的啦!)![]()
![]()

希望对友友们有所帮助!!!!