java中的线程有两种创建方式,继承Thread或者是实现Runnable接口。简单的代码如下:

public class ThreadDemo01 extends Thread{
    int count = 1;
    int number;
    public ThreadDemo01(int num){
        number = num;
        System.out.println("创建线程  "+number);
    }
    public void run(){
        while (true) {
            System.out.println("线程  "+number+":计数 "+count);
            if(++count==10)
                return;
        }
    }
    public static void main(String[] args) {
        for (int i = 0; i <3; i++) {
            new ThreadDemo01(i+1).start();
        }
    }
}

--------------------------------------------------------------------------------------------

public class RunableDemo01 implements Runnable{
    
    int count = 1;
    int number;
    public RunableDemo01(int num){
        number = ++num;
        System.out.println("开启线程   "+number);
    }
    
    public static void main(String[] args) {
        
        for (int i = 0; i < 3; i++) {
            RunableDemo01 r = new RunableDemo01(i);
            Thread thread = new Thread(r);
            thread.start();
        }
    }

    @Override
    public void run() {
        while(true){
            System.out.println("线程  "+number+":计数"+count);
            if(++count==10)
                return;
        }
    }
}

实现Runnable接口创建多线程时,需要借助Thread类,因为Runnable没有提供任何东西支持多线程,必须借助Thread类的框架来实现多线程。

通过Thread类编写多线程程序时,需要用到start()和run()方法。

1、程序员必须覆盖(重写)run()方法,把需要多线程执行的代码放入函数体(方法体)中。如果没有覆盖该方法,程序可以顺利编译通过,但是即使调用start()方法,程序也无法找到多线程执行的代码,所以相当于单线程代码。

线程的状态可以用以下一张图片表示:

 有关于线程阻塞的问题:

 通过一下几种情况,线程可以从被阻塞状态回到可运行状态:

1、线程被置于睡眠状态,并且已经过了指定毫秒数;

2、线程等待I/O操作的完成,且该操作已经完成;

3、线程正在等待另一个线程所持有的锁,且另一个线程已经释放该锁的所有权;(也可能等待超时。当超时发生时,线程解除阻塞。)

4、线程正在等待某个触发条件,且另一个线程已经发出了信号表明条件已经发生改变。(如果线程的等待设置了一个超时,那么当超时发生时该线程将解除阻塞)

5、线程已被挂起,且有人调用了它的resume方法。不过由于suspend方法已经过时,resume方法也就随之被弃用,你不应该在代码中调用它。