java多线程&并发及单例简述

进程和线程

1. 进程:一个正在执行中的程序就是一个进程,系统会为这个进程发配独立的资源。
2. 线程:具体执行任务的最小单位,一个进程至少包含一个线程。

进程与线程的联系:

1.一个进程至少包含一个线程“主线程(main)”,运行起来就执行的线程
2.线程间的资源是共享的,是统一由进程申请的
3.线程间可以通信

io 为阻塞io
nio 为非阻塞io =》netty框架

进程内多个线程间的切换(统一由内核进行调度)
线程的原理简述多线程实现:

1.继承Thread类

public class BThread extends Thread{

    @Override
    public void run() {
        for (int i=0;i<10;i++){
            System.out.println("我是run");
        }
    }

    public static void main(String[] args) {
        for (int i=0;i<10;i++){
            System.out.println("main");
        }
        
        new BThread().start();

        for (int i=0;i<10;i++){
            System.out.println("main2");
        }
    }

}

2.实现Runnable接口

public class BRunnable implements Runnable{

    @Override
    public void run() {
        for (int i=0;i<10;i++){
            System.out.println("我是run");
        }
    }

    public static void main(String[] args) {
        for (int i=0;i<10;i++){
            System.out.println("main");
        }

        new Thread(() -> System.out.println("lamda")).start();

        for (int i=0;i<10;i++){
            System.out.println("main2");
        }
    }

}
-------------------------------------------------------
//lamda表达式实现
public class BRunnable {
    
    public static void main(String[] args) {
        for (int i=0;i<10;i++){
            System.out.println("main");
        }

        new Thread(() -> System.out.println("lamda")).start();

        for (int i=0;i<10;i++){
            System.out.println("main2");
        }
    }

}

实现含返回值的线程(继承Callable接口)
获取返回值 .get()方法 该方法是阻塞属性的

public class BCallable /*implements Callable<Integer>*/{

    /*@Override
    public Integer call() throws Exception {
        Thread.sleep(2000);
        return 1;
    }*/

    public static void main(String[] args) throws Exception {
        System.out.println("2");
        FutureTask<Integer> future = new FutureTask<>(() -> {
                Thread.sleep(2000);
                return 1;
        });
        System.out.println("3");
        new Thread(future).start();
        Integer integer = future.get();
        System.out.println("4");
        System.out.println(integer);
        System.out.println("5");
    }

}

守护线程(对于后台支持非常有用 如:垃圾回收 JVM等)

线程分为 用户线程 和 守护线程
······用户线程优先级高于守护线程 (守护线程为用户线程提供服务)
···········例:JVM在终止任务前等待所有用户线程完成其任务
设置:setDaemon(true) 该线程被设置为守护线程

CPU内存模型:(多级缓存机制)

  • cpu通过数据一致性协议来保证各程序读取数据的一致。
  • 伪共享:数据一致性导致数据在一处一经更改,则该数据在其他缓存中失效
  • 指令重排

磁盘中数据按顺序读取
主存中数据按随机读取

  • cup经过一二三级缓存依次进行查询查到则返回,未查到则在内存中进行读取
    在这里插入图片描述
    JMM(JAVA内存模型)
    JVM内存模型JAVA中的锁:
    synchronized jdk内置锁
    在这里插入图片描述java反编译可见:指令代码 锁由两个标志 monitorenter(获取锁) monitorexit(释放锁)
    反编译指令:D:\workingspace\java\IDEA\prac\out\production\prac\com\idea\thread>javap -v BThread.class
    在这里插入图片描述synchronzied锁升级:
    在这里插入图片描述Lock接口 显式锁
    所要实现的方法
@Override
    public void lock() {}

    @Override
    public void lockInterruptibly() throws InterruptedException {}

    @Override
    public boolean tryLock() { return false;}

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {return false;}

    @Override
    public void unlock() {}

    @Override
    public Condition newCondition() {return null;}
//1.
    try{
        lock.lock();
    }catch(){
        
    }finally{
        lock.unlock();
    }
   
    //2.
    if(lock.tryLock()){
        try{
            lock.lock();
        }catch(){

        }finally{
            lock.unlock();
        }
    }else{
        
    }

ReentrantLock
ReadWriteLock接口
读锁 写锁(独占锁 共享锁)
公平锁 非公平锁
乐观锁 被关锁
可重入锁 不可重入锁

volatile
java虚拟机提供的轻量级的同步机制

  • 保证了数据的可见性,线程访问变量会跳过自己的缓存区从主存中进行读写
  • 禁止指令重排
  • 不保证原子性

线程的生命周期
在这里插入图片描述
在这里插入图片描述
HashMap线程不安全 (ConcurrentHashMap 线程安全且效率高于HashTable)
HashTable线程安全

终止线程的运行

  • 1.设立标志位终止
public class BThread extends Thread {

    public volatile boolean flag = true;

    String name = "";

    public BThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        while (flag) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
                System.out.println(this.name + ":" + Constant.a--);

        }
    }

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

        BThread a = new BThread("zssmb");
        a.start();
        Thread.sleep(1000);
        a.flag = false;
    }

}
  • 2.抛出InterruptedException 异常进行线程终止(打断线程)
    必须包含阻塞方法
public class BThread extends Thread {

    public volatile boolean flag = true;

    String name = "";

    public BThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {

            try {
                while (flag) {
                    Thread.sleep(100);
                    System.out.println(this.name + ":" + Constant.a--);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

    }

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

        BThread a = new BThread("zssmb");
        a.start();
        Thread.sleep(1000);
        a.interrupt();
    }

}

死锁
两个线程A和B,A拿到线程B的锁的同时,B也拿到了线程A的锁,导致两个线程均无法获得各自的锁而形成的死锁

多线程的三大特性
1.原子性()
2.有序性(指令重排问题)
3.可见性(主存和工作内存数据的一致性volatile)

线程池

线程任务传递给线程池,线程池自行调度

提交方法:submit(Runnable task) 提交一个可运行的任务执行,并返回一个表示该任务的未来。

在这里插入图片描述自定义线程池:

public class MyThreadPool {

    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                4,
                8,
                10,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(300),
                new ThreadFactory() {
                    private final AtomicInteger poolNumber = new AtomicInteger(1);
                    private ThreadGroup group = null;
                    private final AtomicInteger threadNumber = new AtomicInteger(1);
                    private String namePrefix = null;

                    {
                        SecurityManager s = System.getSecurityManager();
                        group = (s != null) ? s.getThreadGroup() :
                                Thread.currentThread().getThreadGroup();
                        namePrefix = "prac-" +
                                poolNumber.getAndIncrement() +
                                "-thread-";
                    }
                    public Thread newThread(Runnable r) {
                        Thread t = new Thread(group, r,
                                namePrefix + threadNumber.getAndIncrement(),
                                0);
                        if (t.isDaemon())
                            t.setDaemon(false);
                        if (t.getPriority() != Thread.NORM_PRIORITY)
                            t.setPriority(Thread.NORM_PRIORITY);
                        return t;
                    }
                }
        );

        while (true){
            Thread.sleep(100);
            threadPool.submit(()-> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("zssmb");
            });
        }

    }

}

线程同步类

  • CountDownLaunch (减法器、门栓)
public class PracCountDownLaunch {

    public static void main(String[] args) throws InterruptedException {
        //创建新的线程池
        ScheduledExecutorService sc = Executors.newScheduledThreadPool(10);
        //门栓
        final CountDownLatch downLatch = new CountDownLatch(5);

        for (int i = 0; i < 10; i++) {
            ThreadUtil.sleep(100);
            int finalI = i;
            sc.submit(()->{
                ThreadUtil.sleep(100);
                System.out.println(finalI);
                ThreadUtil.sleep(100);
                downLatch.countDown();
            });

        }
        //CountDownLatch等待downLaunch减为0  再往后执行
        downLatch.await();
        System.out.println("执行总任务");
        sc.shutdown();
    }
}
  • CyclicBarrier (循环栅栏)
public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
        //创建线程池
        ScheduledExecutorService service = Executors.newScheduledThreadPool(5);
        //最终所要完成的任务
        Runnable main = ()-> System.out.println("总报表");
        //创建循环栅栏
        CyclicBarrier cy = new CyclicBarrier(2,main);

        Runnable tesk = ()-> {
            System.out.println("abc");
            try {
                cy.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        };
        for (int i = 0; i < 2; i++) {
            service.submit(tesk);
            ThreadUtil.sleep(100);
        }
        System.out.println("--------------------");
        //重用cy栅栏
        cy.reset();

        for (int i = 0; i < 2; i++) {
            service.submit(tesk);
            ThreadUtil.sleep(100);
        }

        service.shutdown();
    }
  • Semaphore (信号量)
    一次最多允许5此获取令牌
public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
        //创建线程池
        ScheduledExecutorService service = Executors.newScheduledThreadPool(5);
        //最终所要完成的任务
        Runnable main = ()-> System.out.println("总报表");

        //信号量
        Semaphore semaphore = new Semaphore(5);

        //创建一个原子类
        AtomicInteger j = new AtomicInteger(0);

        Runnable tesk = ()-> {
            try {
                //获取令牌
                semaphore.acquire();
                ThreadUtil.sleep(1000);
                System.out.println(j.getAndIncrement());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
            	//释放令牌
                semaphore.release();
            }

        };

        for (int i = 0; i < 10; i++) {
            service.submit(tesk);
        }

        service.shutdown();
    }

原子类

单例的各种实现
1、饿汉式

public class ESingleton {

    //饿汉式
    private static ESingleton singleton = new ESingleton();

    private ESingleton() {
    }

    public static ESingleton getSingleton() {
        return singleton;
    }

}

2.懒汉式:

public class LSingleton {

    //懒汉式
    private static LSingleton singleton;

    private LSingleton(){}

    //线程不安全
    public static LSingleton getSingleton1() {
        if (singleton == null){
            singleton = new LSingleton();
        }
        return singleton;
    }

    //线程安全 双重锁模式  双重检查
    public static LSingleton getSingleton2() {

        if (singleton == null){
            synchronized (LSingleton.class){
                if (singleton == null){
                    singleton = new LSingleton();
                }
            }
        }
        return singleton;
    }
}

3.静态内部类实现:(常用)

public class StaticSingleton {

    //静态内部类单例模式
    private StaticSingleton(){}

    public static StaticSingleton getInstance(){
        return Inner.singleton;
    }
    
    private static class Inner{

        private static final StaticSingleton singleton = new StaticSingleton();

    }
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值