part1-线程基础

目录页:https://blog.csdn.net/u011294519/article/details/88367808

1.简单的基础知识

(PS:网上很多很全,写在这里只是显得有章法(o´罒`o)哼):

进程和线程的区别:

  1. 进程:程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源
  2. 线程:CPU调度的最小单位

并行和并发的区别:

  1. 并行:同一时刻可以处理事务的能力
  2. 并发: 与时间单位相关,在单位时间内可以处理事务的能力

撸代码阶段:

2.开胃菜

    先来个开胃菜,使用虚拟机管理接口查看线程

import java.lang.management.ManagementFactory;

import java.lang.management.ThreadInfo;

import java.lang.management.ThreadMXBean;

 

/**

 *

 *类说明:展示线程

 */

public class ShowThread {

    public static void main(String[] args) {

           //虚拟机线程管理的接口

           ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();

           ThreadInfo[] threadInfos =

            threadMXBean.dumpAllThreads(false, false);

           for(ThreadInfo threadInfo:threadInfos) {

                  System.out.println("["+threadInfo.getThreadId()+"]"+" "

                                +threadInfo.getThreadName());

           }

    }

}

    代码在sharing-collaboration模块中

    运行结果如下

    Monitoring Thread参照Oracle官方文档:

    https://docs.oracle.com/cd/E13188_01/jrockit/docs50/userguide/apstkdmp.html

    其他线程想了解的参照:http://ifeve.com/jvm-thread/

3.线程启动

    简单的线程启动方式(这里简单的意思是不考虑线程池):继承Thread类,实现Runnable接口和Callable接口。

    实现Runnable接口和Callable最大的区别就是Runnable无返回值,Callable有返回值。

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.FutureTask;

 

/**

 *

 *类说明:如何新建线程

 */

public class NewThread {

 

    /**

     * 实现Runnable接口

     */

       private static class UseRun implements Runnable{

 

        @Override

              public void run() {

                     System.out.println("I am implements Runnable");

              }

             

       }

 

    /**

     * 实现Callable接口,允许有返回值

     */

       private static class UseCall implements Callable<String>{

 

              @Override

              public String call() {

                     System.out.println("I am implements Callable");

                     return "CallResult";

              }

             

       }     

      

       public static void main(String[] args)

                     throws InterruptedException, ExecutionException {

        /*

            真实项目中启动线程最好使用线程池,

            否则有可能导致创建大量同类线程消耗完内存,

            也会增加线程间切换的成本(有可能切换时间比程序执行时间还要长)

         */

              UseRun useRun = new UseRun();

              new Thread(useRun).start();

 

              // Thread不支持Callable,所以借用FutureTask

              UseCall useCall = new UseCall();

              FutureTask<String> futureTask = new FutureTask<>(useCall);

              new Thread(futureTask).start();

              System.out.println(futureTask.get());

       }

}

代码在sharing-collaboration模块part1

4.线程停止

  1. stop()不建议使用,因为无法保证线程资源被完全释放
  2. suspend()和resume()方法:

    这两个方法是配对使用的,suspend()方法就是将一个线程挂起(暂停),不会释放资源,会造成死锁;resume()方法就是将一个挂起线程复活继续执行。

    interrupt()是建议使用的停止线程的方法。Java线程是协作式的,interrupt()并不是强行关闭当前线程,而是打个招呼,将该线程的中断标志位设置为true。isInterrupted()方法用于判断当前线程是否处于中断状态。

package com.concurrent.coline.part1.end;

 

/**

 *类说明:中断Runnable类型的线程

 */

public class EndRunnable {

      

       private static class UseRunnable implements Runnable{

             

              @Override

              public void run() {

 

                     String threadName = Thread.currentThread().getName();

                     while(!Thread.currentThread().isInterrupted()) {

                            System.out.println(threadName+" is run!");

                     }

                     System.out.println(threadName+" interrput flag is "

                                   +Thread.currentThread().isInterrupted());

              }                   

       }

 

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

              UseRunnable useRunnable = new UseRunnable();

              Thread endThread = new Thread(useRunnable,"endThread");

              endThread.start();

              Thread.sleep(20);

              endThread.interrupt();

       }

 

}

运行结果:

代码在sharing-collaboration模块part1

    InterruptedException异常(很纠结要不要放在这里说,想了下InterruptedException也是和线程停止相关的):线程抛出        InterruptedException异常时会将线程中断标志位复位,即设置为true,线程无法停止。

package com.concurrent.coline.part1.end;

 

import java.text.SimpleDateFormat;

import java.util.Date;

 

/**

 *

 *类说明:抛出InterruptedException异常的时候,要注意中断标志位

 */

public class HasInterrputException {

      

       private static SimpleDateFormat formater

              = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss_SSS");

      

       private static class UseThread extends Thread{

             

              public UseThread(String name) {

                     super(name);

              }

             

              @Override

              public void run() {

                     String threadName = Thread.currentThread().getName();

                     while(!isInterrupted()) {

                            try {

                                   System.out.println("UseThread:"+formater.format(new Date()));

                                   Thread.sleep(3000);

                            } catch (InterruptedException e) {

                                   System.out.println(threadName+" catch interrput flag is "

                                                 +isInterrupted()+ " at "

                                                 +(formater.format(new Date())));

                                   // 测试的时候可以把这个注释打开看看

                                   // interrupt();

                                   e.printStackTrace();

                            }

                            System.out.println(threadName);                     

                     }

                     System.out.println(threadName+" interrput flag is "

                                   +isInterrupted());

              }

       }

 

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

              Thread endThread = new UseThread("HasInterrputEx");

              endThread.start();

              System.out.println("Main:"+formater.format(new Date()));

              Thread.sleep(800);

              System.out.println("Main begin interrupt thread:"+formater.format(new Date()));

              endThread.interrupt();

             

 

       }

 

}

5.线程优先级

线程优先级:1~10,缺省为5,但是线程优先级取决于操作系统,所以只需要了解下。

6.守护线程

守护线程与主线程同生共死,注意:守护线程的finally代码块中的内容不一定会执行

package com.concurrent.coline.part1.daemon;

 

/**

 * 守护线程

 */

public class DaemonThread {

    private static class DemoThread extends Thread {

        @Override

        public void run() {

            try {

                String threadName = Thread.currentThread().getName();

                while(!isInterrupted()){

                    System.out.println(threadName+" is running");

                }

                System.out.println(threadName+" interrput flag is "

                        +Thread.currentThread().isInterrupted());

 

            } finally {

                // 守护线程中finally不一定会执行

                System.out.println("attention this part is not run in daemon thread");

            }

        }

    }

 

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

        //守护线程,与主线程(main)同生共死

        DemoThread demoThread = new DemoThread();

        // 设置为守护线程,必须要在start之前

        demoThread.setDaemon(true);

        demoThread.start();

        Thread.sleep(10);

        //demoThread.interrupt();

    }

}

       运行结果:

       代码在sharing-collaboration模块的part1

猜你喜欢

转载自blog.csdn.net/u011294519/article/details/88367754