欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-10 19:10:44
线程的创建方式一 :继承Threadpublic 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 Int...

线程的创建

方式一 :继承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 {
......
}

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

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

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

方式四:通过自定义线程池
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() :谦让

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