public class ThreadTest {
public static void main(String[] args) {
System.out.println("main...start...");
// 1. 继承Thread类
Thread01 thread01 = new Thread01();
thread01.start(); // 启动线程
System.out.println("main...end...");
}
public static class Thread01 extends Thread{
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
}
}
}
测试结果:
1.1.2 实现 Runnable 接口
public class ThreadTest {
public static void main(String[] args) {
System.out.println("main...start...");
// 1. 继承Thread类
//Thread01 thread01 = new Thread01();
//thread01.start(); // 启动线程
// 2. 实现Runnable接口
Runnable01 runnable01 = new Runnable01();
new Thread(runnable01).start();
System.out.println("main...end...");
}
public static class Thread01 extends Thread{
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
}
}
public static class Runnable01 implements Runnable{
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
}
}
}
1.1.3 实现 Callable 接口 + FutureTask
FutureTask的get()方法,阻塞式等待整个线程的执行完成,获取线程执行返回结果。
public class ThreadTest {
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start...");
// 1. 继承Thread类
//Thread01 thread01 = new Thread01();
//thread01.start(); // 启动线程
// 2. 实现Runnable接口
//Runnable01 runnable01 = new Runnable01();
//new Thread(runnable01).start();
// 3. 实现Callable接口+FutureTask (可以拿到返回结果,可以处理异常)
Callable01 callable01 = new Callable01();
FutureTask futureTask = new FutureTask<>(callable01);
new Thread(futureTask).start();
// 阻塞式等待整个线程执行完成,获取线程执行返回结果
Integer integer = futureTask.get();
System.out.println("main...end..."+integer );
}
public static class Thread01 extends Thread{
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
}
}
public static class Runnable01 implements Runnable{
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
}
}
public static class Callable01 implements Callable{
@Override
public Integer call() throws Exception {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
return i;
}
}
}
注意:
Future可以获取异步执行结果;
FutureTask继承了Runnable接口。
1.1.4 线程池
public class ThreadTest {
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start...");
// 1. 继承Thread类
//Thread01 thread01 = new Thread01();
//thread01.start(); // 启动线程
// 2. 实现Runnable接口
//Runnable01 runnable01 = new Runnable01();
//new Thread(runnable01).start();
// 3. 实现Callable接口+FutureTask (可以拿到返回结果,可以处理异常)
//Callable01 callable01 = new Callable01();
//FutureTask futureTask = new FutureTask<>(callable01);
//new Thread(futureTask).start();
阻塞式等待整个线程执行完成,获取线程执行返回结果
//Integer integer = futureTask.get();
// 在以后的业务代码里面,以上三种启动线程的方式都不用,因为频繁的创建和销毁线程耗费系统资源。【将所有的多线程异步任务都交给线程池执行】
//new Thread(()-> System.out.println("hello")).start();
// 4. 线程池 给线程池直接提交业务
// 当前系统中池只有一两个(例如:核心业务/非核心业务),每个异步任务,提交给线程池让它自己去执行就行
executorService.execute(new Runnable01());
System.out.println("main...end...");
}
public static class Thread01 extends Thread{
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
}
}
public static class Runnable01 implements Runnable{
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
}
}
public static class Callable01 implements Callable{
@Override
public Integer call() throws Exception {
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+i);
return i;
}
}
}
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
200,
10,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
public CompletableFuture whenComplete(BiConsumer action)
public CompletableFuture whenCompleteAsync(BiConsumer action)
public CompletableFuture whenCompleteAsync(BiConsumer action, Executor executor)
public CompletableFuture exceptionally(Function fn)
public class ThreadTest {
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start...");
//CompletableFuture future = CompletableFuture.runAsync(() -> {
// System.out.println("当前线程:" + Thread.currentThread().getId());
// int i = 10 / 2;
// System.out.println("运行结果:" + i);
//}, executorService);
/**
* 方法执行完成后的感知
*/
//CompletableFuture future = CompletableFuture.supplyAsync(() -> {
// System.out.println("当前线程:" + Thread.currentThread().getId());
// int i = 10 / 2;
// System.out.println("运行结果:" + i);
// return i;
//}, executorService).whenComplete((result,exception)->{
// // 可以感知到异常,但无法修改返回数据
// System.out.println("异步任务完成了...返回值为:"+result+";异常为:"+exception);
//}).exceptionally(throwable -> {
// // 可以感知异常,同时返回默认值
// return 10;
//});
/**
* 方法执行完成后的处理
*/
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("运行结果:" + i);
return i;
}).handle((res, thr) -> {
if (res != null) {
return res * 2;
}
if (thr != null) {
return 10;
}
return 0;
});
// R apply(T t, U u);
Integer integer = future.get();
System.out.println("main...end..."+integer);
}
}
有异常情况
将 int i = 10/4; 改为 int i = 10/0;
1.3.4 线程串行化
public CompletableFuture thenApply(Function fn)
public CompletableFuture thenApplyAsync(Function fn)
public CompletableFuture thenApplyAsync(Function fn, Executor executor)
public CompletableFuture thenAccept(Consumer action)
public CompletableFuture thenAcceptAsync(Consumer action)
public CompletableFuture thenAcceptAsync(Consumer action,Executor executor)
public CompletableFuture thenRun(Runnable action)
public CompletableFuture thenRunAsync(Runnable action)
public CompletableFuture thenRunAsync(Runnable action,Executor executor)
public class ThreadTest {
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start...");
/**
* 两个任务组合-都要完成
*/
CompletableFuture future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:"+Thread.currentThread().getId());
int i = 10/4;
System.out.println("任务1结束。。。");
return i;
}, executorService);
CompletableFuture future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:"+Thread.currentThread().getId());
System.out.println("任务2结束。。。");
return "Hello";
}, executorService);
future01.runAfterBothAsync(future02,()->{
System.out.println("任务3开始");
},executorService);
System.out.println("main...end...");
}
}
执行结果:
1.3.5.2 thenAcceptBothAsync
public class ThreadTest {
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start...");
/**
* 两个任务组合-都要完成
*/
CompletableFuture future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:"+Thread.currentThread().getId());
int i = 10/4;
System.out.println("任务1结束。。。");
return i;
}, executorService);
CompletableFuture future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:"+Thread.currentThread().getId());
System.out.println("任务2结束。。。");
return "Hello";
}, executorService);
//future01.runAfterBothAsync(future02,()->{
// System.out.println("任务3开始");
//},executorService);
future01.thenAcceptBothAsync(future02,(f1,f2)->{
//void accept(T t, U u);
System.out.println("任务3开始。。。之前的结果:"+f1+"->"+f2);
},executorService);
System.out.println("main...end...");
}
}
执行结果:
1.3.5.3 thenCombineAsync
public class ThreadTest {
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start...");
/**
* 两个任务组合-都要完成
*/
CompletableFuture future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:"+Thread.currentThread().getId());
int i = 10/4;
System.out.println("任务1结束。。。");
return i;
}, executorService);
CompletableFuture future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:"+Thread.currentThread().getId());
System.out.println("任务2结束。。。");
return "Hello";
}, executorService);
//future01.runAfterBothAsync(future02,()->{
// System.out.println("任务3开始");
//},executorService);
//future01.thenAcceptBothAsync(future02,(f1,f2)->{
// //void accept(T t, U u);
// System.out.println("任务3开始。。。之前的结果:"+f1+"->"+f2);
//},executorService);
CompletableFuture future = future01.thenCombineAsync(future02, (f1, f2) -> {
return f1 + "->" + f2 + "->相柳"; // R apply(T t, U u);
}, executorService);
System.out.println("main...end..."+future.get());
}
}
执行结果:
1.3.6 两个任务组合 - 一个完成
public CompletableFuture applyToEither(CompletionStage other, Function fn)
public CompletableFuture applyToEitherAsync(CompletionStage other, Function fn)
public CompletableFuture applyToEitherAsync(CompletionStage other, Function fn,Executor executor)
public CompletableFuture acceptEither(CompletionStage other, Consumer action)
public CompletableFuture acceptEitherAsync(CompletionStage other, Consumer action)
public CompletableFuture acceptEitherAsync(CompletionStage other, Consumer action,Executor executor)
public CompletableFuture runAfterEither(CompletionStage other,Runnable action)
public CompletableFuture runAfterEitherAsync(CompletionStage other,Runnable action)
public CompletableFuture runAfterEitherAsync(CompletionStage other,Runnable action,Executor executor)
@Controller
public class ItemController {
@GetMapping("/{skuId}.html")
public String item(@PathVariable Long skuId){
System.out.println("准备查询:"+skuId+"的详情!");
return "item";
}
}
2.1.5 模型抽取
封装页面需要的详情数据模型,如下:
@Data
public class SkuItemVo {
// 获取sku的基本信息 pms_sku_info
private SkuInfoEntity info;
// 获取sku的图片信息 pms_sku_images
private List images;
// 获取spu的销售属性组合
private List saleAttr;
// 获取spu的介绍
private SpuInfoDescEntity desc;
// 获取spu的规格参数信息
private List groupAttrs;
}
@ToString
@Data
public class SpuItemAttrGroupVo {
private String groupName;
private List attrs;
}
// 之前代码中存在
@Data
public class Attr {
private Long attrId;
private String attrName;
private String attrValue;
}
@ToString
@Data
public class SkuItemSaleAttrVo {
private Long attrId;
private String attrName;
private List attrValues;
}
@Data
public class AttrValueAndWithSkuIdVo {
// 属性值
private String attrValue;
// 属性编号,属性名,属性值对应的所有skuId
private String skuIds;
}
2.1.6 商品详情的业务代码
2.1.6.1 controller层
@Controller
public class ItemController {
@Resource
private SkuInfoService skuInfoService;
@GetMapping("/{skuId}.html")
public String item(@PathVariable Long skuId, Model model){
// 获取sku的基本信息 pms_sku_info
// 获取sku的图片信息 pms_sku_images
// 获取spu的销售属性组合
// 获取spu的介绍
// 获取spu的规格参数信息
SkuItemVo vo = skuInfoService.item(skuId);
model.addAttribute("item",vo);
return "item";
}
}
@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl implements SkuInfoService {
@Resource
private SkuImagesService skuImagesService;
@Resource
private SpuInfoDescService spuInfoDescService;
@Resource
private AttrGroupService attrGroupService;
@Resource
private SkuSaleAttrValueService skuSaleAttrValueService;
...
@Override
public SkuItemVo item(Long skuId) {
SkuItemVo skuItemVo = new SkuItemVo();
// 获取sku的基本信息 pms_sku_info
SkuInfoEntity info = getById(skuId);
skuItemVo.setInfo(info);
Long spuId = info.getSpuId();
Long catalogId = info.getCatalogId();
// 获取sku的图片信息 pms_sku_images
List images = skuImagesService.getImagesBySkuId(skuId);
skuItemVo.setImages(images);
// 获取spu的销售属性组合
List saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(spuId);
skuItemVo.setSaleAttr(saleAttrVos);
// 获取spu的介绍
SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(spuId);
skuItemVo.setDesc(spuInfoDescEntity);
// 获取spu的规格参数信息
List attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(spuId,catalogId);
skuItemVo.setGroupAttrs(attrGroupVos);
return skuItemVo;
}
}
2.1.6.3 获取sku的图片信息
public interface SkuImagesService extends IService {
...
List getImagesBySkuId(Long skuId);
}
@Service("skuImagesService")
public class SkuImagesServiceImpl extends ServiceImpl implements SkuImagesService {
...
@Override
public List getImagesBySkuId(Long skuId) {
List imagesEntities = this.baseMapper.selectList(new QueryWrapper().eq("sku_id", skuId));
return imagesEntities;
}
}
2.1.6.4 获取spu的规格参数
public interface AttrGroupService extends IService {
...
List getAttrGroupWithAttrsBySpuId(Long spuId, Long catalogId);
}
@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl implements AttrGroupService {
...
@Override
public List getAttrGroupWithAttrsBySpuId(Long spuId, Long catalogId) {
List vos = this.baseMapper.getAttrGroupWithAttrsBySpuId(spuId,catalogId);
return vos;
}
}
@Mapper
public interface AttrGroupDao extends BaseMapper {
List getAttrGroupWithAttrsBySpuId(@Param("spuId") Long spuId, @Param("catalogId") Long catalogId);
}
2.1.6.5 获取spu的销售属性组合
public interface SkuSaleAttrValueService extends IService {
...
List getSaleAttrsBySpuId(Long spuId);
}
@Service("skuSaleAttrValueService")
public class SkuSaleAttrValueServiceImpl extends ServiceImpl implements SkuSaleAttrValueService {
...
@Override
public List getSaleAttrsBySpuId(Long spuId) {
List vos = this.baseMapper.getSaleAttrsBySpuId(spuId);
return vos;
}
}
@Mapper
public interface SkuSaleAttrValueDao extends BaseMapper {
List getSaleAttrsBySpuId(@Param("spuId") Long spuId);
}
A ROWID is an identification tag unique for each row of an Oracle Database table. The ROWID can be thought of as a virtual column, containing the ID for each row.
The oracle.sql.ROWID class i
public class DeleteNode_O1_Time {
/**
* Q 60 在O(1)时间删除链表结点
* 给定链表的头指针和一个结点指针(!!),在O(1)时间删除该结点
*
* Assume the list is:
* head->...->nodeToDelete->mNode->nNode->..
格式定义The format specifiers supported by the NSString formatting methods and CFString formatting functions follow the IEEE printf specification; the specifiers are summarized in Table 1. Note that you c
概念
AngularJS is a structural framework for dynamic web apps.
了解更多详情请见原文链接:http://www.gbtags.com/gb/share/5726.htm
Directive
扩展html,给html添加声明语句,以便实现自己的需求。对于页面中html元素以ng为前缀的属性名称,ng是angular的命名空间