java编程思想 并发阅读(一)


基础知识概念

这是java编程思想并发一节阅读的阅读笔记。
某些编程语言被设计为可以将并发任务彼此隔离,这些语言通常被称为函数型语言。如果项目中有很多并发就应该考虑函数型语言。
并发最直接的方式是操作系统的进程。进程是运行在自己的地址空间内的自包容程序,他不会和其他进程共享某些资源,彼此间不会有过多的干涉。
Thread.yield(); 是一种建议,java线程机制的一部分,可以将CPU从一个线程转移给另一个线程,它在声明我已经完成了生命周期中最重要的费部分了,此刻是切换给其他任务的好时机。这个方法只是一个声明,并没有特别的机制来确定这种操作一定会实现。
java SE5 中执行器(Executor)将为你管理Thread对象。

   ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            executorService.execute(()->{
                System.out.println(Thread.currentThread().getName());
            });
        }
        executorService.shutdown();
    }

常见的情况是单个Executor用来创建和管理系统中所有的任务。
shutdown()方法就是管理线程池,避免线程池一直在运行。
Executors.newFixedThreadPool(5);也可以使用该工具类创建固定长度的线程池。这个线程池一次性分配固定的资源,可以减少资源的分配,可以快速得到服务。newCachedThreadPool();在程序执行过程中会产生与需求数量相同的线程。在回收线程的时候停止创建新的线程,newCachedThreadPool();是线程的首选。
newSingleThreadExecutor()是线程数为1的fixedThreadPool,方便用于那种希望在一个线程中长久存在的任务。
如果向singleThread提交多个任务,那么这些任务将排队,每个任务都会在下个任务开始运行之前结束,所有任务都将在一个线程上执行
任何一个继承了Runable接口的类应该当成一个任务task 然后他们的线程是Executors分配的。同时线程执行也是这个工具执行的。
Runable是执行工作的独立任务。Callable接口可以有返回值。

//这里callable的使用方式和runable是一样的效果
    private static class CanCall implements Callable<String>{
        @Override
        public String call() throws Exception {

            return "hello callable";
        }
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
       FutureTask<String> futureTask = new FutureTask<>(new CanCall());
       new Thread(futureTask).start();//把接口对象放置到线程类上运行这个和runable接口不一样,他是使用了FutureTask对象,有点像那种适配器的模式
        System.out.println(futureTask.get());
        //使用Executors 方法产生返回值
           ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> submit = executorService.submit(new CanCall());
        String s = submit.get();
        submit.isDone();//用来查看任务是否完成
        System.out.println(s);
    }

sleep()休眠,这将使任务中止给定的时间,对sleep()的调用可以抛出InterruptedException,所有这种异常不能够跨线程传回main线程,所以应该在本线程内部处理产生的异常。
线程的执行顺序是不确定的,但是调度器,优先调度优先级高的线程。getPriority()方法可以获取线程的优先级,也可以随时使用setPriority()来设置线程的优先级。
yield()调用时,是在建议具有相同优先级的其他线程可以运行了。在线程屌的的过程中不应该过度的依赖yield()方法。因为该方法只是建议,没有确定的机制让该方法被执行。
setDaemon()可以将线程设置为后台线程。必须在线程启用前,不然会抛出异常。可以调用isDaemon()方法来确定一个线程是否是后台线程。后台线程中创建的线程自动为后台线程。
start()方法在构造器中调用,有的时候是安全的,但是也有可能不是安全的,因为任务访问的对象还不处在一个稳定的状态,所以最好不要在够着器中调用。
thread1.join();a线程调用调用thread1的join()方法 就是要等thread1线程执行完了,才会继续执行本线程。
异常不能够跨线程捕获,所以一但异常逃出run方法,它就会向外传递到控制台,不是那么容易捕获的。所以线程里面的异常应该在run方法中捕获

共享受限资源

共享资源问题就是那种你的左右手同时往你的嘴巴送东西的问题。
解决共享资源的方法就是,当资源被一个任务使用时,在其加上锁,这样其他线程就无法使用该资源。
java提供关键字synchronized,为防止资源冲突提供了内置支持。当任务要执行被synchronized关键字保护的代码片段的时候,它将检查锁是否可用,然后获取锁,执行代码,释放锁。
共享资源一般是以对象形式存在的内存片段,但也可以是文件、输入\输出端口,或者是打印机等。
所有对象都自动含有单一的锁(也称为监视器),当在对象上调用其任意synchronized方法的时候,此对象都会被加锁,此时该对象上的其他synchronized方法只有等到前一个方法调用完毕,并释放了锁之后才能够被调用,对于某个特定对象来说,其所有synchronized方法共享同一个锁,这可以被用来防止多个任务同时访问被编码为对象内存。

如果你正在写一个变量,它可能接下来将被另一个线程读取,或者正在读取上一次已经被另一个线程写过的变量,那么你必须使用同步,并且读写线程都必须用相同的监视器锁同步。
lock必须这样显示的加锁,显示的释放。和synchronized相比代码更多,但是更加灵活。一般情况使用synchronized,synchronized关键字出现错误的概率也要低一些。lock可以更加细粒度的控制竞态资源。

Lock lock = new ReentrantLock();
        lock.lock();
        lock.unlock();

原子性

long double变量都是64位的读取写入操作,是当做两个32位操作来执行的,这也就产生了在读取和写入操作中间发生的上下文切换,从而导致了相同的操作,得到了不同的结果。

volatile 如果将一个域定义,就会告诉编译器不要执行任何移除读取操作和写入操作的优化,这样所有的操作都是针对内存,没有任何缓存。voliatie不能对不是原子性的操作产生任何影响。
jse5提供 AtomicInteger AtomicLong AtomicBoolean AtomicReference等特殊的原子性变量类。对这些原子性变量的操作,他们就是具有原子性的。

线程状态

线程四个状态
新建(new):当线程被创建时,它只会短暂处于这种状态,此时它已经分配了必须的系统资源,并执行了初始化。此时线程已经又资格获取CPU时间了,之后调度器就可以把该线程转变为可运行状态或阻塞状态了。
就绪(runable):这种状态下,只要调度器把时间片分配给线程,线程就可以运作。
阻塞:线程可以运行,但是某个条件阻止他的运行,当线程处于阻塞状态的时候,当线程处于阻塞状态的时候,调度器将忽略线程,只有当线程重新处于就绪状态的时候才又能够分配到时间片。
死亡:线程结束生命周期了。
通过调用sleep()使任务进入休眠状态,在这种情况下,任务在指定的时间内是不会运行的。
当你通过调用wait()使线程挂起,直到线程得到了noitfy()或者noitfyall()消息的时候就又会进入就绪状态。
当任务在等待某个I/O的时候
任务视图在某个对象上调用其同步控制方法,但是对象锁不可用。因为另一个任务已经获取了这个锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值