Java 高并发系列
1. java 多线程编程系列之一【synchronized关键字】 2. Java多线程编程系列之二【Lock接口】 3. java 多线程编程系列之三【可重入锁与公平锁】 4. java 多线程编程系列之四【继承Thread类与实现Runnable方法】 5. 5

java 多线程编程系列之四【继承Thread类与实现Runnable方法】

Java创建线程的两种方式

方式

  • 继承Thread类
  • 实现Runnable方法

 

实例

#继承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-1 剩余个数 10

Thread-0 剩余个数 10

Thread-0 剩余个数 9

Thread-1 剩余个数 9

Thread-0 剩余个数 8

Thread-1 剩余个数 8

Thread-0 剩余个数 7

Thread-1 剩余个数 7

Thread-1 剩余个数 6

Thread-0 剩余个数 6

Thread-1 剩余个数 5

Thread-0 剩余个数 5

Thread-1 剩余个数 4

Thread-0 剩余个数 4

Thread-1 剩余个数 3

Thread-0 剩余个数 3

Thread-0 剩余个数 2

Thread-1 剩余个数 2

Thread-0 剩余个数 1

Thread-1 剩余个数 1

 

 

#实现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-0 剩余个数 10

Thread-1 剩余个数 10

Thread-2 剩余个数 8

Thread-3 剩余个数 7

Thread-1 剩余个数 6

Thread-3 剩余个数 5

Thread-2 剩余个数 6

Thread-0 剩余个数 6

Thread-1 剩余个数 2

Thread-0 剩余个数 2

Thread-2 剩余个数 2

Thread-3 剩余个数 2

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

 

比较

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

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

涉及到线程的几个状态

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

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

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

 

 

区别

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

 


package com.jihite.helloworld.thread;



public class TestNoStart {

    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("ping~~~~");

    }

    static void pong(int i) {

        System.out.println("pong~" + i);

    }

}