Java 多线程-----基础篇

1  线程和进程的区别

  • 进程:是操作系统进行资源分配和调度的基本单位,每个进程拥有独立的内存空间、文件描述符、寄存器等资源
  • 线程:是进程内的一个执行单元,是CPU调度的基本单位。线程共享进程的资源

2  多线程实现方式

2.1 继承Thread

下面是一个简单的例子 ,通过运行结果我们可以看到两个任务是并行的。

public class Demo1 {
    public static  void  main(String [] args){
        Demo1 demo1 = new Demo1();
        demo1.fun1();

    }
    public void fun1(){

            ThreadDemo threadDemo1 = new ThreadDemo();
            ThreadDemo threadDemo2 = new ThreadDemo();
            threadDemo1.start();
            threadDemo2.start();
    }
    class ThreadDemo extends Thread{
        private int count = 0;
        public ThreadDemo(){

        }
        public void  run(){
           for(int i = 0 ;i<100;i++){
               System.out.println(i);
           }
        }
    }
} 

2.2 实现Runnable类

在这里用到了Thread类的构造函数Thread(Runnable target),Runnale是一个函数式接口,函数式接口。就是里面只能有一个需要实现的接口,这意味我们可以使用Lambda表达式来简化程序

public class Demo1 {
    public static  void  main(String [] args){
        Demo1 demo1 = new Demo1();
        demo1.fun1();

    }
    public void fun1(){

        ThreadDemo threadDemo1 = new ThreadDemo();
        ThreadDemo threadDemo2 = new ThreadDemo();
        new Thread(threadDemo1).start();
        new Thread(threadDemo2).start();
    }
    class ThreadDemo implements Runnable{
        private int count = 0;
        public ThreadDemo(){

        }
        public void  run(){
            for(int i = 0 ;i<100;i++){
                System.out.println(i);
            }
        }
    }
}

2.3 实现Callable

特点是能通过FutureTask拿到结果

/**
 * Callable 例子
 */
public class CallableDemo {
    public static  void main(String []args){
       CallableDemo callableDemo = new CallableDemo();
       callableDemo.fun();
    }

    public void fun(){
        FutureTask<String> futureTask = new FutureTask<String>(callable);
        try {
            System.out.println(futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("hhhhhhs");
    }

    private Callable<String> callable = new Callable<String>() {
        @Override
        public String call() throws Exception {
            Thread.sleep(2000);
            return "I want to be greater";
        }
    };
}

2.4 线程池实现

线程池主要好处就是避免线程频繁的创建和销毁,增加对系统的开销。

线程池详细介绍:https://www.cnblogs.com/minblog/p/16352356.html

public class DemoTask {
    public static void main(String[] args) {
        ExecutorService executorService1 = Executors.newFixedThreadPool(1);
        executorService1.execute(()->{System.out.println("22222");});
    }
}

3 线程的一些常用方法和状态变更

sleep(long millis) : 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)

sleep(long millis, int nanos) 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)

join():等待该线程终止 ;  

join( long millis) : 也是等待该线程终止,不过最大时间为millis毫秒。

yield() :让当前线程主动放弃CPU资源,进行就绪状态。

getPriority() / setPriority(int priority)  获取/设置线程优先级,优先级高的更可能被CPU调度

setDaemon(boolean on) : 设置成守护线程,当所有非守护进程结束时,守护线程会自动终止。JVM会等待所有非守护线程结束后才停止,设计的目的是为其他非守护线程提供服务

interrupt(): 向线程发送中断信号,非强制终止,可以用于优雅终止线程, 如下面代码所示,程序将在运行1s后退出,还有个作用是唤醒阻塞线程,如一些阻塞操作,sleep、join、wait都会catch这个异常,通过主动发送中断,结束阻塞

public class DemoTask {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.interrupted()) {
                    System.out.println(1111);
                }
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
}

  

posted @ 2020-04-14 00:30  一花一世界!  阅读(0)  评论(0)    收藏  举报