zoukankan      html  css  js  c++  java
  • Java线程知识

    线程在多任务处理应用程序中有着至关重要的作用

    概念

    基本概念

    进程:在操作系统中每个独立运行的程序就是一个进程

    线程:程序执行的一个顺序执行流(程序的一个运行路径),一个进程至少有一个线程,线程拥有自己的堆栈、计数器和局部变量,多个线程共享所在进程的系统资源

    并发:cpu在多个进程之间切换

    并行:多个进程在多个不同cpu同时执行

    多进程:多进程和多线程是多任务的两种类型,进程间数据块是相互独立的,进程间通过信号、管道等交互。

    多线程:在多cpu计算机可以真正物理实现,单核计算机只是逻辑实现,由操作系统进行线程管理调度。

    线程生命周期

    新建 -> 就绪:start()
    就绪 -> 运行:获得处理器资源
    运行 -> 就绪:失去处理器资源
    运行 -> 终止: 执行完成或者抛出异常,stop方法
    运行 -> 阻塞: sleep,IO阻塞,等待同步锁,wait()等待其他线程通知(notify),suspend()挂起
    阻塞 -> 就绪: sleep时间到了,IO方法返回,获得同步锁,收到notify()或notifyAll(),resume()恢复
    
    
    
    //stop()容易造成死锁(该方法已过时)
    
    

    Java线程模型

    Thread类

    继承Thread类,其中run()方法用于执行线程要执行的任务,start()方法用于启动线程

    public class Mythread1 extends Thread {
    
        @Override
        public void run() {
            this.setName("我的线程02");
            System.out.println(this.getName());
        }
    
        public static void main(String[] args) {
            Mythread1 mythread1 = new Mythread1();
            mythread1.start();
            System.out.println(Thread.currentThread().getName());
        }
    }
    

    Runnable接口,实现Runnable接口

        public class MyThread2 implements Runnable {
            @Override
            public void run() {
                System.out.println("runnable");
            }
    
            public static void main(String[] args) {
                Thread thread = new Thread(new MyThread2());
                thread.start();
            }
        }
    

    Callable接口,可以返回线程执行的值,通过FutureTask接收,FutureTask实现了RunnableFuture接口,实际上RunnableFuture继承了Runnable和Future接口,特别注意get()方法返回返回值,会造成阻塞

        import java.util.concurrent.*;
    
        public class MyCallable implements Callable<String> {
            private long waitTime;
            public MyCallable(int timeInMillis){
                this.waitTime=timeInMillis;
            }
            @Override
            public String call() throws Exception {
                Thread.sleep(waitTime);
                //return the thread name executing this callable task
                return Thread.currentThread().getName();
            }
    
        }
    
        class FutureTaskExample {
            public static void main(String[] args) {
                MyCallable callable1 = new MyCallable(1000);                       // 要执行的任务  
                MyCallable callable2 = new MyCallable(2000);
    
                FutureTask<String> futureTask1 = new FutureTask<String>(callable1);// 将Callable写的任务封装到一个由执行者调度的FutureTask对象  
                FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
    
                ExecutorService executor = Executors.newFixedThreadPool(2);        // 创建线程池并返回ExecutorService实例  
                executor.execute(futureTask1);  // 执行任务  
                executor.execute(futureTask2);
    
                while (true) {
                    try {
                        if(futureTask1.isDone() && futureTask2.isDone()){//  两个任务都完成  
                            System.out.println("Done");
                            executor.shutdown();                          // 关闭线程池和服务   
                            return;
                        }
    
                        if(!futureTask1.大专栏  Java线程知识 class="na">isDone()){ // 任务1没有完成,会等待,直到任务完成  
                            System.out.println("FutureTask1 output="+futureTask1.get());
                        }
    
                        System.out.println("Waiting for FutureTask2 to complete");
                        String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);
                        if(s !=null){
                            System.out.println("FutureTask2 output="+s);
                        }
                    } catch (InterruptedException | ExecutionException e) {
                        e.printStackTrace();
                    }catch(TimeoutException e){
                        //do nothing  
                    }
                }
            }
        }  
    

    线程方法

    run()线程执行的内容

    start()启动线程

    sleep()线程休眠指定时间,不会释放对象锁

    isAlive()判断线程是否处于激活状态(就绪或运行)

    join()是一个同步方法,父线程等待子线程执行指定时间(若为0则一直等待,直到子线程执行完毕),理解(join(),父线程获得同步代码块,wait一段时间,等待子线程执行完成或时间结束)

    参考

    
    
     public final synchronized void join(long millis)
        throws InterruptedException {
            long base = System.currentTimeMillis();
            long now = 0;
    
            if (millis < 0) {
                throw new IllegalArgumentException("timeout value is negative");
            }
    
            if (millis == 0) {
                while (isAlive()) {
                    wait(0);
                }
            } else {
                while (isAlive()) {
                    long delay = millis - now;
                    if (delay <= 0) {
                        break;
                    }
                    wait(delay);
                    now = System.currentTimeMillis() - base;
                }
            }
        }
    
    
    import static java.lang.Thread.currentThread;
    import static java.lang.Thread.sleep;
    
    public class TestJoin implements Runnable {
    
    
        public static void main(String[] sure) throws InterruptedException {
            Thread t = new Thread(new TestJoin());
            long start = System.currentTimeMillis();
            t.start();
            t.join(100);//等待线程t 1000毫秒
            System.out.println(System.currentTimeMillis()-start);//打印出时间间隔
            System.out.println("Main finished");//打印主线程结束
        }
    
        @Override
        public void run() {
           // synchronized (currentThread()) {
            for (int i = 1; i <= 5; i++) {
                try {
                    sleep(1000);//睡眠5秒,循环是为了方便输出信息
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("睡眠" + i);
            }
            System.out.println("TestJoin finished");//t线程结束
        }
      // }
    }
    
    
    

    static void yield()暂停线程,并允许其他线程执行

    线程优先级

    线程优先级只是指获得资源的机会,并不是执行顺序

    线程同步

    synchronized

    小知识

    多个线程访问同个对象的同步代码块时,同一时刻只能有一个线程得到执行

    一个线程访问一个对象的同步代码块时,其他线程仍可以访问同步代码块

    如果被锁的是类,那么无论new多少实例,同属一个类依然会被锁住,即线程之间通信依旧是同步的

    需要注意的时synchronized关键字无法被继承,子类覆盖同步方法时,可以调用父类方法或显式加上关键字

    定义接口方法不能使用synchronized,构造函数不能用synchronized,但可以用synchronized代码块

    参考

  • 相关阅读:
    mysql的统计函数(聚合函数)
    mysql中的五子查询
    mysql-蠕虫复制--快速插入数据
    mysql 外键的使用
    我的mysql入门笔记
    阿里云官方 Centos7 源码安装 LAMP环境
    xml格式数据转excel
    mysql的安装配置
    sublime中,怎么把所有的函数代码都折叠起来?
    点击文字或按钮弹出一个DIV窗口(DIV悬浮窗口)
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12284256.html
Copyright © 2011-2022 走看看