码迷,mamicode.com
首页 > 编程语言 > 详细

Java基础篇——多线程

时间:2021-03-09 13:00:41      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:mamicode   获取   setdaemon   sys   避免   机制   指定   默认   包含   

  • 创建线程的三种方式

    1.继承Thread类

    2.实现Runnable接口

    3.实现Callable接口

  • 继承Thread类

    public Test extends Thread{
        public void run(){
            ...
        }//必须重写Thread类的Run方法
        ...
        public static void main(String[] args){
            Test test = new test();//先new线程对象
            test.run();//调用线程方法
            test.start();//调用线程
            ...
        }
    }
    

    不同调用方式,cpu执行的方式也不同

    技术图片

    线程开启后不一定立即执行,由cpu调度算法调度执行

    为了验证副线程确实是穿插在主线程中进行的,我把主线程循环次数拉到了千位才成功

    技术图片

  • 实现Runnable接口

    (1)用自定义类实现Runnable接口

    public class RunnableTest implements Runnable{
        ...}
    

    (2)实例化类对象,用Thread线程代理(开启线程)

    RunnableTest test=new RunnableTest();
            new Thread(test).start();//线程代理
    

    避免单继承的局限性,推荐使用实现Runnable接口方法,可实现对多个对象的代理

  • 实现Callable接口

    ExecutorService ser = Executors.newFixedThreadPool(1) //创建执行服务(固定大小(n)的线程池)
    Future<Boolean> result1 = ser.submit(t1);//提交执行:
    boolean r1 = result1.get()//获取结果
    ser. shutdownNow();//关闭服务
    //Callable接口需要有返回值类型    implements Callable<T>{}
    //与此同时,必须重写带有T型返回值的Call方法
    
Lamda表达式
  • 函数式接口:只包含一个抽象方法的接口

    //  (参数)->{...方法体};
    //单参数时可省略括号
    //单行方法体可以省略花括号
    //只有函数式接口可以用Lamda表达式,下方是一个实现Runnable接口的Lamda表达式
    Runnable a=()->System.out.println("this is Lamda");
           a.run();
    
线程状态

技术图片

线程方法
  • Thread thread=new Thread();
    //线程启动
    thread.start();
    //线程停止(盲目调用线程停止方法有风险,推荐使用标志量停止线程)
    thread.stop();
    thread.destory();
    //线程礼让,停止该线程,重新调度
    thread.yield();
    //线程睡眠,以毫秒为单位
    thread.sleep()
    //强制执行该线程,阻塞其他线程
    thread.join();
    //获取线程状态
    thread.getState();
    //获取和修改线程优先级
    thread.getPriority();
    thread.setPriority(int);
    //设置守护线程(随用户线程死亡而死亡)
    thread.setDaemon(boolean);
    
线程同步

? 并发:多个线程同时操作同一对象

? 为了避免访问冲突,在访问时加入锁机制synchronized,保证访问线程独占资源

? 修饰符synchronized可以将一个方法或者块修饰为同步方法/同步块,同步方法必须获得调用该方法的对象的锁,才能拿被执行,方法执行时独占该锁,执行完毕才能开锁。

? 同步方法的锁对象默认是当前this类对象,如果所共享资源不在该对象中,则可以用同步块实现同步

  • synchronized(Object){...}//Object为实际需要同步的锁对象
    

? 可重入锁,ReentrantLock

  • class A{
        private final ReentrantLock lock = new ReenTrantLock();
        public void m(){
            lock.lock();
            try{
               //保证线程安全的代码;
            } finally{
                lock.unlock();
                //如果同步代码有异常,要将unlock()写入finally语句块
            }
        }
    }
    
线程通信
  • wait()//表示线程一直等待,直到其他线程通知,与sleep不同,会释放锁
    wait(long timeout)//指定等待的毫秒数
    notify()//唤醒一个处于等待状态的线程
    notifyAll()//唤醒同-一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度
    
线程池

在经常需要线程创建和销毁的大型程序中,使用线程池可以避免资源浪费,实现重复利用。

使用方法类似于Callable接口实现,提供了两种执行线程的方法

  • execute(new Thread);//无返回值的线程执行
    submit(new Thread);//带返回值的线程执行,返回值为一个Future<boolean>类型
    

Java基础篇——多线程

标签:mamicode   获取   setdaemon   sys   避免   机制   指定   默认   包含   

原文地址:https://www.cnblogs.com/wtlbbdbk/p/14497580.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!