线程的创建

方式一 :继承Thread
public class ThreadTest  extends  Thread{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("Thread:"+i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        ThreadTest threadTest = new ThreadTest();
        threadTest.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main:"+i);
            //TimeUnit.SECONDS.sleep(1);
        }
    }

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=49985:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;E:\idea_workplace\javaBase\target\classes" 
main:0
main:1
main:2
thread:1
main:3
thread:2
main:4
main:5
main:6
main:7
main:8
main:9
main:10
。。。。
方式二:实现Runnable接口
public class RunnerbleTest {
    public static void main(String[] args) {
        new Thread(new A(),"A").start();
        new Thread(new A(),"B").start();
    }
    static class  A implements Runnable{
        @Override
        public void run() {
            int i = 5;
            while (i-->=0){
                System.out.println(Thread.currentThread().getName()+"==="+Thread.currentThread().getState());
            }
        }
    }
}
B===RUNNABLE
A===RUNNABLE
A===RUNNABLE
A===RUNNABLE
A===RUNNABLE
B===RUNNABLE
B===RUNNABLE
B===RUNNABLE
A===RUNNABLE
B===RUNNABLE
A===RUNNABLE
B===RUNNABLE

方式三:实现Callble接口
public class CallableTest implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        return 1023;
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CallableTest  test = new CallableTest();
        FutureTask futureTask =  new FutureTask<>(test);
        Thread thread = new Thread(futureTask, "A");
        thread.start();
        Object o = futureTask.get();
        System.out.println(o);

    }
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=64112:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA "
1023

Callble创建线程有点绕,我画了一个图(基于源码和API)供大家参考理解,首先我们知道Thread是实现了Runnble接口的,FutureTask也是实现了Runnable接口,而FutureTask依赖Callabe,通过了这种间接的方式创建了线程

public class Thread implements Runnable {
......
}

线程的创建与基本方法的使用_java
这里是通过构造器传入Callable

   public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

线程的创建与基本方法的使用_多线程_02

方式四:通过自定义线程池
public class ThreadPoolExecutorDemo {
    public static void main(String[] args) {
        //自定义线程池,阿里开发手册推荐
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,//核心线程数,就是默认开启线程数
                Runtime.getRuntime().availableProcessors(),//最大线程数
                3,//超时时间
                TimeUnit.SECONDS,//超时单位
                new ArrayBlockingQueue<>(3),//阻塞队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.CallerRunsPolicy()//执行策略
                );
        for (int i = 0; i < 9 ; i++) {
            threadPoolExecutor.execute(()->{
                System.out.println(Thread.currentThread().getName());
            });
        }
        //关闭线程池
        threadPoolExecutor.shutdown();
    }
}

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=50720:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;E:\idea_workplace\javaBase\target\classes" 
pool-1-thread-1
main
pool-1-thread-2
pool-1-thread-4
pool-1-thread-1
main
pool-1-thread-4
pool-1-thread-3
pool-1-thread-2

Process finished with exit code 0

基本方法使用

join()方法

join():强制性加入,并且还要把调用者的线程执行完毕后才给其他线程机会

public class ThreadTest  extends  Thread{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("Thread:"+i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        ThreadTest threadTest = new ThreadTest();
        threadTest.start();
        for (int i = 0; i < 10; i++) {
            if (i == 5){
                threadTest.join();//另外一个线程任务强行加入,执行完毕才继续向下
            }
            System.out.println("main:"+i);
            //TimeUnit.SECONDS.sleep(1);
        }
    }
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=65360:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 
main:0
main:1
main:2
main:3
main:4
Thread:0
Thread:1
Thread:2
Thread:3
Thread:4
Thread:5
Thread:6
Thread:7
Thread:8
Thread:9
main:5
main:6
main:7
main:8
main:9
setDaemon()

新建的线程默认不是守护线程,我们在设置为守护线程时候,必须在start之前设置.。
守护线程重点是守护,守护的对象如果不在了,他也会跟着消亡

public class ThreadTest  extends  Thread{
    @Override
    public void run() {
       while (true){
           System.out.println(520);
       }
    }
    public static void main(String[] args) throws InterruptedException {
        ThreadTest threadTest = new ThreadTest();
        boolean daemon = threadTest.isDaemon();//
        threadTest.setDaemon(true);//
        threadTest.start();
        for (int i = 0; i < 5; i++) {
            System.out.println("main:"+i);
        }
    }
}

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=49270:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program 
main:0
main:1
main:2
main:3
main:4

Process finished with exit code 0

还有一种情况

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=49270:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program 
main:0
main:1
main:2
main:3
main:4
520
520

不是说守护的线程结束了,它也会跟着消亡吗,怎么还运行呢?
这是因为死亡也是需要时间的啊,在这段时间内,它可以做自己的事情。上面那种情况是你死了,我也立刻死。所以才看到只有主线程打印

yield() :谦让

调用本方法时,当前线程谦让一下,让另一个线程执行,但是,另一个线程不一定执行,万一它害羞呢 ????

public class ThreadTest  extends  Thread{
    @Override
    public void run() {
        int i = 0;
       while (i++<30){
           System.out.println(520);
       }
    }
    public static void main(String[] args) throws InterruptedException {
        ThreadTest threadTest = new ThreadTest();
        threadTest.start();
        for (int i = 0; i < 30; i++) {
            if (i == 10){               
                Thread.yield();//
            }
            System.out.println("main:"+i);
            //TimeUnit.SECONDS.sleep(1);
        }
    }
}
main:0
main:1
main:2
main:3
main:4
520
520
520
main:5
main:6
main:7
main:8
main:9
520
520
520
main:10
520
520
520
520
520
520
。。。

等于10的时候谦让了一下,哈哈
下面示范一个害羞的

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=49866:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;E:\idea_workplace\javaBase\target\classes" 
main:0
main:1
main:2
main:3
main:4
main:5
main:6
main:7
main:8
main:9
main:10
main:11
main:12
main:13
main:14
520
。。。。
sleep(long time)

sleep方法会让出CPU的时间片资源,但是不会释放掉获取的锁

wait()

wait方法会让出CPU时间片资源并且释放掉对象的锁

getStackTrace()和StackTraceElement[ ]

跟踪栈信息,得到栈中的元素数组

public class Helloword {
    public static void main(String[] args) {
        new Helloword().a();

    }
    public void a(){
        b();
    }
    public void b(){
        c();
    }
    public void c(){
        d();
    }
    public void d(){
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        if (stackTrace != null){
            for (StackTraceElement element : stackTrace) {
                System.out.println(element);
            }
        }
    }
}

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=56955:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program" Helloword
java.lang.Thread.getStackTrace(Thread.java:1559)
Helloword.d(Helloword.java:16)
Helloword.c(Helloword.java:13)
Helloword.b(Helloword.java:10)
Helloword.a(Helloword.java:7)
Helloword.main(Helloword.java:3)

Process finished with exit code 0