多线程

作者: 磊_5d71 | 来源:发表于2018-10-29 21:44 被阅读0次
    图片.png

    包括线程和等待队列两部分


    图片.png
    package com.alan.designpattern.company;
    
    import com.alan.designpattern.task.CodingTask;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class ThreadTest {
    
    
            public static void main(String[] args) {
                /**
                 *     public ThreadPoolExecutor(int corePoolSize,
                 *                               int maximumPoolSize,
                 *                               long keepAliveTime,
                 *                               TimeUnit unit,
                 *                               BlockingQueue<Runnable> workQueue)
                 *                               构造函数包含5个参数:线程数、最大线程数、最大线程保存时间、线程超时单位,阻塞队列
                 */
                // new ThreadPoolExecutor()
    
                //采用简单的构造方式
                //callable有返回值,runnable没有返回值
                ExecutorService executorService = Executors.newFixedThreadPool(3);
    
                for (int i = 0; i < 10; i++) {
                    executorService.submit(new CodingTask(i));
                }
                System.out.println("10个已运行");
    
            }
    
    
    }
    
    • CodingTask.java
    package com.alan.designpattern.task;
    
    public class CodingTask implements Runnable {
    
      private final int employeeId;
    
      public CodingTask(int employeeId) {
        this.employeeId = employeeId;
      }
    
      @Override
      public void run() {
        System.out.println("Employee " + employeeId
            + " started writing code.");
    
        try {
          Thread.sleep(5000);
        } catch (InterruptedException e) {
          throw new RuntimeException(e);
        }
    
        System.out.println("Employee " + employeeId
            + " finished writing code.");
      }
    }
    
    图片.png
    图片.png

    java里面内存可以被自动回收,但是资源不会,需要try catch finally进行处理。
    数据库连接很珍贵 连接完成之后要及时释放资源,或者采用数据库连接池 最小50 最大连接数200 生产环境

    Mysql 查看及设置事物隔离级别

    1.查看

    SELECT @@transaction_isolation

    2.设置

    2.1所有级别

    1)read uncommitted : 读取尚未提交的数据 :哪个问题都不能解决 2)read committed:读取已经提交的数据 :可以解决脏读 ---- oracle默认的 3)repeatable read:重读读取:可以解决脏读 和 不可重复读 ---mysql默认的 4)serializable:串行化:可以解决 脏读 不可重复读 和 虚读---相当于锁表

    2.2 设置

    设置mysql的隔离级别:set session transaction isolation level 设置事务隔离级别

    图片.png

    update table set count = 45 where product_id= 2 and count = 46;
    count =46相当于加的限制条件,乐观锁一般适用于事务不是特别多的情况下。

    一、乐观锁

    总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或CAS操作实现。

    version方式:一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。

    核心SQL代码:

    update table set x=x+1, version=version+1 where id=#{id} and version=#{version};

    CAS操作方式:即compare and swap 或者 compare and set,涉及到三个操作数,数据所在的内存值,预期值,新值。当需要更新时,判断当前内存值与之前取到的值是否相等,若相等,则用新值更新,若失败则重试,一般情况下是一个自旋操作,即不断的重试。
    一、悲观锁

    总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都需要阻塞挂起。可以依靠数据库实现,如行锁、读锁和写锁等,都是在操作之前加锁,在Java中,synchronized的思想也是悲观锁

    相关文章

      网友评论

          本文标题:多线程

          本文链接:https://www.haomeiwen.com/subject/ufsitqtx.html