java高并发编程学习笔记

一. Thread与虚拟机栈

粗略地认为一个java进程的内存大小为:堆内存+线程数*栈内存。因此线程数量与栈内存的大小是反比关系。

二.守护线程

JVM程序在没有一个非守护线程时,则JVM的进程会退出。也就是说守护线程具有自动结束生命周期的特性。

守护线程经常作为一些后台任务,当希望关闭某些线程的时候,或者退出JVM进程的时候,一些线程能够自动关闭,此时就可以考虑守护ianc来完成这样的工作。

thread.setDaemon(true);//将此线程设置为守护线程。

三.线程interrupt

Object的wait方法;

Thread的join方法;

Thread的join方法;

InterruptibleChannel的io操作;

Selector的wakeup方法;

以上方法的调用会使得当前线程进入阻塞状态,而调用当前线程的interrupt方法,就可以打断阻塞。打断一个线程并不等于改线程的生命周期结束,仅仅是打断了当前线程的阻塞状态。

一旦线程在阻塞的情况下被打断,都会抛出一个成为InterruptedException的异常。

一个线程内部存在着名为interrupt flag的标识,如果一个线程被interrupt,那么它的flag将被设置,但如果当前线程正在执行可中断方法被阻塞是,调用interrupt方法将其中断,反而会导致flag被清除。

 

isInterrupted是Thread的一个成员方法,主要判断当前线程是否被中断,该方法仅仅是对interrupt标识的一个判断,并不会影响标识发生任何变化。

    public void testInterrupt() throws InterruptedException {
        Thread thread = new Thread(){
            @Override
            public void run() {
                while(true) {
                     System.out.println("正在执行!");
                }
            }
        };
        thread.setDaemon(true);
        thread.start();
        TimeUnit.MILLISECONDS.sleep(2);
        System.out.printf("Thread is interrupted? %s\n",thread.isInterrupted());
        thread.interrupt();
        System.out.printf("Thread is interrupted? %s\n",thread.isInterrupted());
    }

 Thread is interrupted? false
 Thread is interrupted? true

 

public void testInterrupt() throws InterruptedException {
        Thread thread = new Thread(){
            @Override
            public void run() {
                while(true) {
                    System.out.println("正在执行!");
                    try {
                        TimeUnit.MINUTES.sleep(1);
                    } catch (InterruptedException e) {
                        System.out.printf("线程是否被中断? %s\n",isInterrupted());
                        e.printStackTrace();

                    }
                }
            }
        };
        thread.setDaemon(true);
        thread.start();
        TimeUnit.MILLISECONDS.sleep(2);
        System.out.printf("Thread is interrupted? %s\n",thread.isInterrupted());
        thread.interrupt();
        System.out.printf("Thread is interrupted? %s\n",thread.isInterrupted());
    }

Thread is interrupted? false
线程是否被中断? false
Thread is interrupted? false

interrupted是一个静态方法,判断当前线程是否被中断,调用该方法会直接擦除线程的interrupt标识,如果线程被打断,第一次调用interrupted方法会返回true,并且立即擦除interrupt标识;以后的调用都会返回false,除非在此期间线程又一次被打断。

四.正常关闭一个线程

1.捕获中断信号关闭线程

public void testInterrupt() throws InterruptedException {
        Thread thread = new Thread(){
            @Override
            public void run() {
                while(!isInterrupted()) {

                        System.out.println("正在执行!");

                }
            }
        };
        thread.setDaemon(true);
        thread.start();
        TimeUnit.MILLISECONDS.sleep(2);
        System.out.printf("Thread is interrupted? %s\n",thread.isInterrupted());
        thread.interrupt();
        System.out.printf("Thread is interrupted? %s\n",thread.isInterrupted());

2.使用volatile开关控制

由于线程的interrupt标识很有可能被擦除,或者不会调用任何可中断方法,所以使用volatile修饰的开关flag关闭线程更常用。

private volatile boolean run = true;
    @Test
    public void testInterrupt() throws InterruptedException {
        Thread thread = new Thread(){
            @Override
            public void run() {
                while(run) {

                        System.out.println("正在执行!");

                }
            }
        };
        thread.setDaemon(true);
        thread.start();
        TimeUnit.MILLISECONDS.sleep(2);
        run = false;
    }

 

你可能感兴趣的:(java)