包括线程和等待队列两部分
图片.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 设置事务隔离级别
图片.pngupdate 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的思想也是悲观锁
网友评论