java并发编程实战wwj----------------------第一阶段--------------11-12-13-14-15

守护线程:

代码:chapter4

都是放在一个ThreadGroup去管理的。

守护线程必须在start之前设置的。

public class DaemonThread {

    public static void main(String[] args) throws InterruptedException {

        Thread t = new Thread() {

            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread().getName() + " running");
                    Thread.sleep(100000);
                    System.out.println(Thread.currentThread().getName() + " done.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }; //new
        t.setDaemon(true);
        t.start();

        //runnable  ->running| ->dead| ->blocked


        Thread.sleep(5_000);   //JDK1.7
        System.out.println(Thread.currentThread().getName());
    }
}

为什么要设置守护线程?

创建连接线程创建之后我们用守护线程做心跳检查。创建连接线程死了则守护的心跳线程也跟着死掉了。

问题:子线程是守护线程,父亲是非守护,父亲死了,儿子就死了。

代码:

 public static void main(String[] args) {

        Thread t = new Thread(() -> {
            Thread innerThread = new Thread(() -> {
                try {
                    while (true) {
                        System.out.println("Do some thing for health check.");
                        Thread.sleep(1_000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            innerThread.setDaemon(true);
            innerThread.start();

            try {
                Thread.sleep(10000);
                System.out.println("T thread finish done.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        //t.setDaemon(true);
        t.start();
        System.out.println("main dead");
    }

问题:子线程是非守护线程,父亲是守护线程,父亲随着main线程死,但是子线程不死,main线程死了,子线程才死。

package one.chapter4;

/***************************************
 * @author:Alex Wang
 * @Date:2017/2/17 QQ:532500648
 * QQ交流群:286081824
 ***************************************/
public class DaemonThread2 {
    public static void main(String[] args) {

        Thread t = new Thread(() -> {
            Thread innerThread = new Thread(() -> {
                try {
                    while (true) {
                        System.out.println("Do some thing for health check.");
                        Thread.sleep(1_000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            //innerThread.setDaemon(true);
            innerThread.start();

            try {
                Thread.sleep(10000);
                System.out.println("T thread finish done.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.setDaemon(true);
        t.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main dead");
    }
}

问题:父亲线程是非守护线程,儿子是非守护线程,儿子自由。

主线程和子线程:https://blog.csdn.net/zhenwei1994/article/details/78779230

public static void main(String[] args) {

        Thread t = new Thread(() -> {
            Thread innerThread = new Thread(() -> {
                try {
                    while (true) {
                        System.out.println("Do some thing for health check.");
                        Thread.sleep(1_000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            //innerThread.setDaemon(true);
            innerThread.start();

            try {
                Thread.sleep(10000);
                System.out.println("T thread finish done.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        //t.setDaemon(true);
        t.start();
        System.out.println("main dead");
    }

写守护线程的时候,注意守护线程start起来之后不一定马上跑的,是runnable状态的。

------------------------------------------12------------------------------------

线程的优先级:

java8语法:http://www.ibloger.net/article/3209.html

 public static void main(String[] args) {
        Thread t = new Thread(() -> {
            Optional.of("Hello").ifPresent(System.out::println);
            try {
                Thread.sleep(100_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");

        t.start();
        Optional.of(t.getName()).ifPresent(System.out::println);
        Optional.of(t.getId()).ifPresent(System.out::println);
        Optional.of(t.getPriority()).ifPresent(System.out::println);
    }

看下这个id是怎么来的?

源码:

public long getId() {
        return tid;
    }
tid = nextThreadID();
   private static synchronized long nextThreadID() {
        return ++threadSeqNumber;
    }

id就是线程的个数的值。

线程的优先级:分配时间片倾斜,不是很准,不要指望。数大优先级高。

设置优先级:https://blog.csdn.net/weixin_44071658/article/details/85008774

---------------------------13--------------------------------

join方法:

代码:chapter5

   public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(
                () -> {
                    IntStream.range(1, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
                }
        );
        t1.start();
        t1.join();
        IntStream.range(1, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
    }

a.join()就等a执行完毕。

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(
                () -> {
                    IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
                }
        );
        Thread t2 = new Thread(
                () -> {
                    IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
                }
        );
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
    }

注意此时是join在main线程里面,Thread1和Thread2是交互执行的。

t1,t2是随机执行的。

加入等待的时长:

 public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(
                () -> {
                    System.out.println("t1_start");
                    try {
                        Thread.sleep(10_100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t1_end");
                }
        );
        Thread t2 = new Thread(
                () -> {
                    IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
                }
        );
        t1.start();
//        t2.start();
        t1.join(10_100,10);//  毫秒+纳秒
//        t2.join();
        IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
    }

必须是先start再join的。

一个问题:

       启动时候是一个守护线程,比如通信什么的,主线程挂掉后就终结了。

       

 让主线程一直等着。就是main线程等我main线程结束。

看下这个代码;

package one.chapter5;

/***************************************
 * @author:Alex Wang
 * @Date:2017/2/17 QQ:532500648
 * QQ交流群:286081824
 ***************************************/
public class ThreadJoin2 {
    public static void main(String[] args) {
        /*Thread t1 = new Thread(() -> {
            try {
                System.out.println("t1 is running");
                Thread.sleep(10_000);
                System.out.println("t1 is done");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        t1.start();
        t1.join(100,10);


        Optional.of("All of tasks finish done.").ifPresent(System.out::println);
        IntStream.range(1, 1000)
                .forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));*/

        //start httpServer
//        JettyHttpServer.start();

//        Thread.currentThread().join();
        Thread main = Thread.currentThread();

        Thread t1 = new Thread(() -> {
            while (true) {
                try {
//                    System.out.println("t1 is running");
//                  System.out.println(Thread.currentThread().isInterrupted());
                    if(Thread.currentThread().isInterrupted()){
                       System.out.println("true");
//                       break;
                    }
//                    Thread.sleep(10);
                } catch (Exception e) {
                    e.printStackTrace();
//                    break;
                }
            }

        });
        t1.start();
        Thread t2 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                Thread.currentThread().interrupt();
//                main.interrupt();
                t1.interrupt();
//                System.out.println("interrupt");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        });
        t2.start();

        try {
            t1.join(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("end");

    }
}

 一个知识点:

t.join则要t.inturrept.

此时如果t线程不是sleep则不会抛出异常只会标识位显示,而且不会使join失效的。

t.join则main打断就都断了,直接end。

---

一个需求:采集服务器节点的数据。

一个很简单的数据采集系统:

public class ThreadJoin3 {

    public static void main(String[] args) throws InterruptedException {
        long startTimestamp = System.currentTimeMillis();
        Thread t1 = new Thread(new CaptureRunnable("M1", 10000L));
        Thread t2 = new Thread(new CaptureRunnable("M2", 30000L));
        Thread t3 = new Thread(new CaptureRunnable("M3", 15000L));

        t1.start();
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();

        long endTimestamp = System.currentTimeMillis();
        System.out.printf("Save data begin timestamp is:%s, end timestamp is:%s\n", startTimestamp, endTimestamp);
    }

}

class CaptureRunnable implements Runnable {

    private String machineName;

    private long spendTime;

    public CaptureRunnable(String machineName, long spendTime) {
        this.machineName = machineName;
        this.spendTime = spendTime;
}

    @Override
    public void run() {
        //do the really capture data.
        try {
            Thread.sleep(spendTime);
            System.out.printf(machineName + " completed data capture at timestamp [%s] and successfully.\n", System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public String getResult() {
        return machineName + " finish.";
    }
}

------------------------------------14---------------------------------------

没有捕获到线程中断的信号,所以还会一直运行。

如何捕获

其实是会收到信号的。

看下源码:看下仅仅是设置flag标志。

interrupt:

代码:chapter6

看下代码:

package one.chapter6.threadMy;

public class ThreadMy {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            public void run(){
                while(true){
                    try{
                        System.out.println(123);
                        Thread.sleep(10_000);
                      }catch(InterruptedException e){
                        System.out.println("收到打断信号");
                        e.printStackTrace();
                        System.out.println(">>"+this.isInterrupted());
                       }
                }
            }
        };
        t.start();
        Thread.sleep(1000);
        System.out.println(t.isInterrupted());
        t.interrupt();
        System.out.println(t.isInterrupted());
    }
}

运行结果:

代码:

执行结果:

其实还是再死循环里面的。

必须在sleep的时候才可以抛出中断异常。

注意中断了但是还是要走程序的。

只是中断了sleep或者wait。

有这几种方式:

代码,测试下wait的打断方法:

package one.chapter6.threadMy;

public class ThreadWait {
    private static final Object MONITOR = new Object();
    public static void main(String[] args) throws InterruptedException {

        Thread t = new Thread() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("888");
                    synchronized (MONITOR) {
                        try {
                            MONITOR.wait(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            System.out.println(isInterrupted()+"123");
                        }
                    }
                }
            }
        };

        t.start();
        Thread.sleep(100);
        System.out.println(t.isInterrupted());
        t.interrupt();
        System.out.println(t.isInterrupted());
    }
}

运行结果:

虽然打断但是还是在死循环,我们可以直接stop

----------

为什么有这个方法:isInterrupted(),我们看下这个为什么没有t.,因为目前就是在线程的方法中。

我们用两种方式来定义下线程。

1.

2.我们看下源码

代码:

--------

join也是可以打断的。

代码:

 Thread t = new Thread() {
            @Override
            public void run() {
                while (true) {

                }
            }
        };

        t.start();
        Thread main = Thread.currentThread();
        Thread t2 = new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                main.interrupt();
                System.out.println("interrupt");
            }
        };

        t2.start();
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

join是join到main线程,打断的应该是打断的是main线程。

sleep是t的sleep

wait是t的wait

join是join到main里面要打断main

---------------------------------15----------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值