精华内容
下载资源
问答
  • 2010年7月份总结

    2011-09-04 22:56:42
    1.上半月仍然是按步就班的进行基线开发,任务虽重,基本可以按照项目的计划进度来,还算OK。徒弟经过公司的配需和项目组的实习,也渐入佳境,基本可以完成一些简单的工作。   2.上半月空闲的时间,再一次仔细的查...

    好久没有写总结了,这一段时间发生了很多事情,今天有空闲,先补上7月份的总结。

     

    7月份的核心就是出差和旅游。当然不是出差就是旅游,而是出差后回来又去旅游。呵呵。

     

    总结如下:

    1.上半月仍然是按步就班的进行基线开发,任务虽重,基本可以按照项目的计划进度来,还算OK。徒弟经过公司的配需和项目组的实习,也渐入佳境,基本可以完成一些简单的工作。

     

    2.上半月空闲的时间,再一次仔细的查看了一下《Thinking in Java 4th》中的IO流操作和多线程部分,简单学习了NIO,仔细看了相关的Demo,了解生产者/消费者模型、线程池、并发原子类等部分的知识。买了一本书叫做《java concurrency in practice》,真的不错,开始学习学习。学习Socket网络编程的部分,温故而知新。

     

    3.去参加了一个淘宝的技术嘉年华活动,聆听了一些大牛的Report,收获不小。最意外的看到了很多比较有名的大牛,很开心兴奋,这次活动真的没白参加。

     

    4.下半月的主题1就是出差了。大概19号出发的,29号才回来。这一次出差还是去弄广州的项目。出差麻烦呀,需要应付硬件、软件、领导、对接的工作人员,比写代码麻烦多了。东西很碎,流程很乱,都需要好好规划。出差几天,就没出去玩过,虽然辛苦,但是最后项目解决了,还是蛮开心的,收获也很到。技术方面的东西,我的其他几篇博客里面有描述到。主要是非技术的东西,我觉得十分有必要总结一下。

    a.出差前的资料准备要充足,但是不要分类太多。东西精就好,资料太多,需要的时候找不到是很麻烦的事情。

    b.做事情一定要有很好的规划,每一个步骤最好想好,不然就会发现做了很多无用功。忙了好久,最后解决的就是一个简单的问题。

    c.平时积累的东西要全面,硬件知识、操作系统知识等都要积累,不同的操作系统总要装过几次吧,服务器的一些基本信息总要认识一些。

    d.代码不是玩具,实验室的东西总要出来跑跑,只有放到真实情况下运行运行,才会发现问题并解决问题。

    e.与人合作,一定要注意沟通的方式、内容、时机。如果需要一些资源,最好再用之前就进行申请和沟通,从而保证任务的并行化。

    f.遇到问题,别只看表面。其实问题可能是由一个很简单的小问题引起的。

    g.别留下自己知道的Bug,问题一直留在那里让自己心理一直不放松。直面问题的勇气,也是程序员需要培养的品质。

     

    这次出差心情大好,收获了很多,完成了所有的问题,心理的疙瘩彻底去掉了,happy。

     

    5.主题2就是旅游。公司组织旅游,30号出发去湖南的张家界。说来也巧,本来是几个不同团的好兄弟,机缘巧合就凑到一个团里面去了,大家一路有说有笑,还一起吃了一次大排档,聊聊人生,叙叙家常,真的不错。张家界真的很美,人也美,拿着新买得相机,照了很多给力的照片。身体得到了彻底的放松,美中不足的就是旅游回来俊哥和马哥就要离职了,短期内估计是看不到了,有点不舍,祝二位日后发展顺利,马到功成。

     

    当然,自己也有很多不足,一定要指出的。存在的问题如下:

    1.遇到问题时要冷静,要平和的很身边的人进行沟通。

    2.注意身体,不要一工作起来就不注意,身体抗议的时候自己就吃不消了。

    3.心态要好,要学会调节自己的心情,不以物喜,不以己悲。每一个人都有迷茫的时刻,没什么大不了。

     

    下个月的事情,都已经是过去时了,下篇再说吧。

     

    专注!!!!

    因为坚持,所以简单!!

     

     

     

     

     

     

    展开全文
  • Inno Setup 是一个免费的安装制作软件,小巧、简便、精美是其最大特点,支持pascal脚本,能快速制作出标准Windows2000风格的安装界面,足以完成一般安装任务。该软件用Delphi写成,其官方网站同时也提供源程序免费...
  • 公众号关注“视学算法”设为 “星标”,重磅干货,第一时间送达!来源 | 机器之心预训练是当前计算机视觉领域的主要范式,但何恺明等人先前的研究发现,预训练对目标检测和分割任务的影响有限。...

    公众号关注 “视学算法

    设为 “星标”,重磅干货,第一时间送达!

    来源 | 机器之心

    预训练是当前计算机视觉领域的主要范式,但何恺明等人先前的研究发现,预训练对目标检测和分割任务的影响有限。因而,重新探究预训练和自训练的效果成为一个非常重要的课题。在这篇谷歌团队的论文中,Quoc V. Le 等研究者发现,当具有大量的标注数据时,自训练的运行效果要优于预训练,并在 COCO 检测和 PASCAL 分割任务上实现了 SOTA 结果。

    众所周知,预训练是计算机视觉领域的主导范式,研究人员也热衷于预训练。

    但是,预训练真的有用吗?

    早在 2018 年,何恺明等人在论文《Rethinking ImageNet Pre-training》中重新思考了 ImageNet 预训练模型。他们发现这种利用预训练模型抽取「通用」特征,并借此解决大多数视觉任务的方法是值得质疑的。因为即使在比 ImageNet 还大 3000 倍的数据集上进行预训练,它们对目标检测任务的性能提升仍然不是很大。

    近日,谷歌大脑研究团队首席科学家 Quoc V. Le 公布了其团队的一项新研究,主题是「重新思考预训练和自训练」。在这篇论文中,谷歌研究者展示了当标注数据很多时,预训练不起作用。相比之下,当标注数据很多时,自训练可以运行良好,并在 PASCAL 分割和 COCO 检测数据集上实现 SOTA 效果

    关于自训练,谷歌团队先前已经展开相关研究,分别是在 ImageNet 数据集上实现 SOTA 的 Noisy Student Training 和在 LibriSpeech 数据集上实现 SOTA 的 Noisy Student Training for Speech。

    而这项新研究则是对先前研究成果的延续,该研究发现:在大型数据集上取得优秀结果需要自训练(w/Noisy Student)。

    接下来,我们来看这项研究的具体内容。

    论文链接:https://arxiv.org/pdf/2006.06882.pdf

    预训练是计算机视觉领域中的主要范式。例如,监督式 ImageNet 预训练常用于初始化目标检测和分割模型的主干网络。但是,何恺明等人的研究展示了一个令人惊讶的结果,即 ImageNet 预训练对 COCO 目标检测任务的影响有限。

    于是,谷歌大脑的研究人员将自训练作为另一种在相同设置上利用额外数据的方法进行研究,并将其与 ImageNet 预训练进行对比。该研究展示了自训练的通用性和灵活性,并发现以下三点洞见:

    1. 更强的数据增强和更多标注数据,却使得预训练的价值降低;

    2. 与预训练不同,在提供更强大的数据增强时,自训练通常起到积极作用,不论是在低数据机制还是高数据机制下;

    3. 在预训练有用的情况下,自训练比预训练更有用。

    例如,在 COCO 目标检测数据集上,研究人员使用 1/5 的标注数据时,预训练起到积极影响,但当使用全部标注数据时,准确率反而下降。而自训练在所有数据集规模下都能带来 1.3 至 3.4AP 的性能提升,即自训练在预训练不起作用的场景下依然有效。在 PASCAL 分割数据集上(该数据集比 COCO 小很多),尽管预训练起到很大的作用,但自训练带来的性能提升更大。

    在 COCO 目标检测任务中,自训练实现了 54.3AP,相比最强大的预训练模型 SpineNet 提升了 1.5AP;在 PASCAL 分割任务中,自训练实现了 90.5 mIOU,相比之前的最优结果(来自 DeepLabv3+)提升了 1.5%

    如何对比预训练和自训练

    方法和控制因子

    这部分涉及数据增强、预训练和自训练三个方面。

    1. 数据增强

    该研究使用四种适用于目标检测和分割任务的不同数据增强策略,分别是:FlipCrop、AutoAugment、具备更高 scale jittering 的 AutoAugment 以及具备更高 scale jittering 的 RandAugment。(下文中,这四种数据增强策略分别写作 Augment-S1、Augment-S2、Augment-S3 和 Augment-S4。)

    2. 预训练

    为了评估预训练的效果,研究者对不同质量的 ImageNet 预训练模型检查点进行了研究。此外,为了控制模型容量,所有检查点均使用同样的模型架构,不过由于训练方法不同,它们在 ImageNet 上的准确率有所不同。

    该研究使用 EfficientNet-B7 架构 [51] 作为预训练的强基线方法。EfficientNet-B7 架构有两个可用的检查点:1)使用 AutoAugment 训练的 EfficientNet-B7 检查点,它在 ImageNet 上的 top-1 准确率为 84.5%;2)使用 Noisy Student 方法训练的 EfficientNet-B7 检查点,它利用额外 300M 无标注图像,实现了 86.9% 的 top-1 准确率。该研究将这两个检查点分别写为 ImageNet 和 ImageNet++。基于随机初始化进行训练的模型即 Rand Init。

    下表 1 展示了该研究所用数据增强和预训练检查点的定义:

    3. 自训练

    该研究使用的自训练实现基于 Noisy Student training [10],共有三个步骤:1)基于标注数据(如 COCO 数据集)训练教师模型;2)教师模型基于无标注数据(如 ImageNet 数据集)生成伪标签;3)训练学生模型,对人类标签和伪标签上的损失进行联合优化

    学生模型中的主要噪声来源是数据增强和相关模型之前使用过的其他噪声扰动方法。

    预训练 VS 自训练,谁赢?

    数据增强和标注数据量对预训练的影响

    谷歌研究人员将前述何恺明的研究进行了扩展,发现了以下几点:

    1. 在使用强大的数据增强时,预训练会损伤模型性能。

    研究者改变数据增强的强度,并分析对预训练的影响。如下图 1 左图所示,在使用标准数据增强(Augment-S1)时,预训练起到积极作用。但随着数据增强强度的增加,预训练的价值逐渐减退。

    图 1:数据增强和数据集规模对预训练的影响。

    2. 更多标注数据反倒会降低预训练的价值。

    研究者分析了标注数据集规模变化时,预训练的影响。如上图 1 右图所示,在低数据机制(20%)下预训练产生积极影响,但在高数据机制下,预训练的作用是中性甚至有害的。

    这一结果与何恺明的观察基本一致。不过该研究还有一项新发现:检查点质量与低数据机制下的最终性能有关(ImageNet++ 在 20% COCO 数据集上的性能最优)。

    数据增强和标注数据集规模对自训练的影响

    研究者对自训练展开分析,并将其与上述结果进行了对比。出于一致性的考虑,研究人员继续使用 COCO 目标检测任务,并以 ImageNet 数据集作为自训练数据源。与预训练不同,自训练将 ImageNet 数据集仅作为无标注数据。

    1. 自训练在高数据 / 强数据增强的机制下能够起到积极作用,而预训练则不能。

    研究者首先分析了数据增强强度对目标检测器性能的影响。下表 2 展示了使用四种数据增强策略时自训练的性能变化,并将这些结果与监督学习(Rand Init)和预训练(ImageNet Init)进行了比较。

    表 2:使用四种数据增强方法时自训练的性能变化,以及与监督学习和预训练的比较。

    2. 自训练适用于不同规模的数据集,是对预训练的补充。

    研究者接下来分析了不同 COCO 标注数据集规模对自训练性能的影响。

    如下表 3 所示,自训练在小数据集和大数据集上都对目标检测器起到积极作用。最重要的是,在 100% 标注数据集规模的高数据机制下,自训练显著提升了所有模型的性能,而预训练则损害了模型性能。

    表 3:自训练可以在所有规模的标注数据集上提升模型性能,而预训练无法实现该效果。

    自训练在高数据/强数据增强机制下起到积极作用,自监督预训练则不能

    研究者还研究了另一种流行的预训练方法:自监督学习。

    如下表 4 所示,自监督预训练检查点在 COCO 数据集上对性能的损害与监督预训练方法相当。与使用随机初始模型(randomly initialized model)相比,自监督和监督预训练模型的性能均下降了 0.7AP。相较于它们,自训练模型将性能提升了 0.8AP。

    此外,尽管自监督学习和自训练都忽略了标签,但在使用无标注 ImageNet 数据增强 COCO 数据集方面,自训练似乎更有效。

    表 4:在 COCO 数据集上,自监督 / 监督预训练与自训练对模型性能的影响。

    探索自训练和预训练的极限

    研究者结合了数据增强、自训练和预训练的相互作用来提升 SOTA 结果,具体如下表 5 和下表 6 所示:

    表 5:在 COCO 目标检测数据集上的结果。

    表 6:在 PASCAL VOC 语义分割数据集上的结果。

    重新思考预训练和自训练

    重新思考预训练和通用特征表示

    计算机视觉的目标之一是开发能够解决多项任务的通用特征表示。而该研究实验通过预训练和自训练的性能差异,展示了在分类和自监督任务中学习通用表示的局限性。

    研究人员对预训练性能较弱的直观见解是,预训练无法感知要处理的特定任务,因而无法进行适应。而在任务发生变化时,这样的适应是必要的。例如,适合 ImageNet 的特征可能缺失对 COCO 数据集有用的位置信息。

    谷歌研究者得出的结论是:将自训练目标和监督学习进行联合训练,更有利于适应特定任务。这或许能够使自训练产生更普遍的积极影响。

    联合训练的意义

    自训练机制的优势在于,它能联合训练监督和自训练目标,从而解决二者之间的不匹配。那么,联合训练 ImageNet 和 COCO 是否也能解决这种不匹配呢?

    下表 7 展示了将 ImageNet 分类和 COCO 目标检测联合训练的结果:

    表 7:预训练、自训练和联合训练在 COCO 数据集上的对比结果。

    自训练的优势:可扩展性、通用性和灵活性

    实验结果表明自训练具备以下优势:

    • 灵活性:自训练可以很好地应对实验中的每一种设置,如低数据、高数据、弱数据增强和强数据增强。同时自训练对不同的架构(ResNet、EfficientNet、SpineNet、FPN、NAS-FPN)、数据源(ImageNet、OID、PASCAL、COCO)和任务(目标检测、分割)都有效;

    • 通用性:对于预训练失败或成功的场景,自训练都能够应对;

    • 可扩展性:在使用更多标注数据和更好模型时,自训练也能实现优秀的性能。

    机器学习领域的一个苦涩教训是:在具备更多标注数据、更多算力或更好的监督训练方法时,大部分方法会失败,不过这种情况并没有出现在自训练这里。

    自训练的局限性

    现有的自训练方法也有局限。相比基于预训练模型进行微调,自训练需要更多算力。根据预训练模型的质量、数据增强的强度和数据集规模,预训练可实现 1.3 至 1.8 倍的加速。此外,低数据应用(如 PASCAL 分割)也需要优秀的预训练模型。

    展开全文
  • 新春定货会一直都是我们公司一年的中之。本次新春定货会我管辖内有两个批发部:康百汇以及鑫络。其中康百汇年任务100W本次定货会任务按年任务/10*3*1。17的任务标准来计算即任务为35。1W元。鑫络年任务50W,定货...
  • 点击上方好好学java,选择星标公众号重磅资讯、干货,第一时间送达今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~作者:Greta Wang出处:http://www.cnblogs.com/greta/停止一个线程意味着在任务处理完...

      点击上方 好好学java ,选择 星标 公众号

    重磅资讯、干货,第一时间送达d0e1b25e842e5cac4789085ae34b4799.png

    今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~

    作者:Greta Wang
    出处:http://www.cnblogs.com/greta/

    停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。在java中有以下3种方法可以终止正在运行的线程:

    1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
    2. 使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期作废的方法。
    3. 使用interrupt方法中断线程。

    1. 停止不了的线程

    interrupt()方法的使用效果并不像for+break语句那样,马上就停止循环。调用interrupt方法是在当前线程中打了一个停止标志,并不是真的停止线程。

    public class MyThread extends Thread {
    public void run(){
    super.run();
    for(int i=0; i<500000; i++){
    System.out.println("i="+(i+1));
    }
    }
    }

    public class Run {
    public static void main(String args[]){
    Thread thread = new MyThread();
    thread.start();
    try {
    Thread.sleep(2000);
    thread.interrupt();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    输出结果:

    ...
    i=499994
    i=499995
    i=499996
    i=499997
    i=499998
    i=499999
    i=500000

    2. 判断线程是否停止状态

    Thread.java类中提供了两种方法:

    1. this.interrupted(): 测试当前线程是否已经中断;
    2. this.isInterrupted(): 测试线程是否已经中断;

    那么这两个方法有什么图区别呢?我们先来看看this.interrupted()方法的解释:测试当前线程是否已经中断,当前线程是指运行this.interrupted()方法的线程。

    public class MyThread extends Thread {
    public void run(){
    super.run();
    for(int i=0; i<500000; i++){
    i++;
    // System.out.println("i="+(i+1));
    }
    }
    }

    public class Run {
    public static void main(String args[]){
    Thread thread = new MyThread();
    thread.start();
    try {
    Thread.sleep(2000);
    thread.interrupt();

    System.out.println("stop 1??" + thread.interrupted());
    System.out.println("stop 2??" + thread.interrupted());
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    运行结果:

    stop 1??false
    stop 2??false

    类Run.java中虽然是在thread对象上调用以下代码:thread.interrupt(), 后面又使用

    System.out.println("stop 1??" + thread.interrupted());
    System.out.println("stop 2??" + thread.interrupted());

    来判断thread对象所代表的线程是否停止,但从控制台打印的结果来看,线程并未停止,这也证明了interrupted()方法的解释,测试当前线程是否已经中断。这个当前线程是main,它从未中断过,所以打印的结果是两个false.

    如何使main线程产生中断效果呢?

    public class Run2 {
    public static void main(String args[]){
    Thread.currentThread().interrupt();
    System.out.println("stop 1??" + Thread.interrupted());
    System.out.println("stop 2??" + Thread.interrupted());

    System.out.println("End");
    }
    }

    运行效果为:

    stop 1??true
    stop 2??false
    End

    方法interrupted()的确判断出当前线程是否是停止状态。但为什么第2个布尔值是false呢?官方帮助文档中对interrupted方法的解释:测试当前线程是否已经中断。线程的中断状态由该方法清除。 换句话说,如果连续两次调用该方法,则第二次调用返回false。

    下面来看一下inInterrupted()方法。

    public class Run3 {
    public static void main(String args[]){
    Thread thread = new MyThread();
    thread.start();
    thread.interrupt();
    System.out.println("stop 1??" + thread.isInterrupted());
    System.out.println("stop 2??" + thread.isInterrupted());
    }
    }

    运行结果:

    stop 1??true
    stop 2??true

    isInterrupted()并为清除状态,所以打印了两个true。

    3. 能停止的线程--异常法

    有了前面学习过的知识点,就可以在线程中用for语句来判断一下线程是否是停止状态,如果是停止状态,则后面的代码不再运行即可:

    public class MyThread extends Thread {
    public void run(){
    super.run();
    for(int i=0; i<500000; i++){
    if(this.interrupted()) {
    System.out.println("线程已经终止, for循环不再执行");
    break;
    }
    System.out.println("i="+(i+1));
    }
    }
    }

    public class Run {
    public static void main(String args[]){
    Thread thread = new MyThread();
    thread.start();
    try {
    Thread.sleep(2000);
    thread.interrupt();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    运行结果:

    ...
    i=202053
    i=202054
    i=202055
    i=202056
    线程已经终止, for循环不再执行

    上面的示例虽然停止了线程,但如果for语句下面还有语句,还是会继续运行的。看下面的例子:

    public class MyThread extends Thread {
    public void run(){
    super.run();
    for(int i=0; i<500000; i++){
    if(this.interrupted()) {
    System.out.println("线程已经终止, for循环不再执行");
    break;
    }
    System.out.println("i="+(i+1));
    }

    System.out.println("这是for循环外面的语句,也会被执行");
    }
    }

    使用Run.java执行的结果是:

    ...
    i=180136
    i=180137
    i=180138
    i=180139
    线程已经终止, for循环不再执行
    这是for循环外面的语句,也会被执行

    如何解决语句继续运行的问题呢?看一下更新后的代码:

    public class MyThread extends Thread {
    public void run(){
    super.run();
    try {
    for(int i=0; i<500000; i++){
    if(this.interrupted()) {
    System.out.println("线程已经终止, for循环不再执行");
    throw new InterruptedException();
    }
    System.out.println("i="+(i+1));
    }

    System.out.println("这是for循环外面的语句,也会被执行");
    } catch (InterruptedException e) {
    System.out.println("进入MyThread.java类中的catch了。。。");
    e.printStackTrace();
    }
    }
    }

    使用Run.java运行的结果如下:

    ...
    i=203798
    i=203799
    i=203800
    线程已经终止, for循环不再执行
    进入MyThread.java类中的catch了。。。
    java.lang.InterruptedException
    at thread.MyThread.run(MyThread.java:13)

    4. 在沉睡中停止

    如果线程在sleep()状态下停止线程,会是什么效果呢?

    public class MyThread extends Thread {
    public void run(){
    super.run();

    try {
    System.out.println("线程开始。。。");
    Thread.sleep(200000);
    System.out.println("线程结束。");
    } catch (InterruptedException e) {
    System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());
    e.printStackTrace();
    }

    }
    }

    使用Run.java运行的结果是:

    线程开始。。。
    在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false
    java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at thread.MyThread.run(MyThread.java:12)

    从打印的结果来看, 如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变为false。

    前一个实验是先sleep然后再用interrupt()停止,与之相反的操作在学习过程中也要注意:

    public class MyThread extends Thread {
    public void run(){
    super.run();
    try {
    System.out.println("线程开始。。。");
    for(int i=0; i<10000; i++){
    System.out.println("i=" + i);
    }
    Thread.sleep(200000);
    System.out.println("线程结束。");
    } catch (InterruptedException e) {
    System.out.println("先停止,再遇到sleep,进入catch异常");
    e.printStackTrace();
    }

    }
    }

    public class Run {
    public static void main(String args[]){
    Thread thread = new MyThread();
    thread.start();
    thread.interrupt();
    }
    }

    运行结果:

    i=9998
    i=9999
    先停止,再遇到sleep,进入catch异常
    java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at thread.MyThread.run(MyThread.java:15)

    5. 能停止的线程---暴力停止

    使用stop()方法停止线程则是非常暴力的。

    public class MyThread extends Thread {
    private int i = 0;
    public void run(){
    super.run();
    try {
    while (true){
    System.out.println("i=" + i);
    i++;
    Thread.sleep(200);
    }
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    public class Run {
    public static void main(String args[]) throws InterruptedException {
    Thread thread = new MyThread();
    thread.start();
    Thread.sleep(2000);
    thread.stop();
    }
    }

    运行结果:

    i=0
    i=1
    i=2
    i=3
    i=4
    i=5
    i=6
    i=7
    i=8
    i=9

    Process finished with exit code 0

    6.方法stop()与java.lang.ThreadDeath异常

    调用stop()方法时会抛出java.lang.ThreadDeath异常,但是通常情况下,此异常不需要显示地捕捉。

    public class MyThread extends Thread {
    private int i = 0;
    public void run(){
    super.run();
    try {
    this.stop();
    } catch (ThreadDeath e) {
    System.out.println("进入异常catch");
    e.printStackTrace();
    }
    }
    }

    public class Run {
    public static void main(String args[]) throws InterruptedException {
    Thread thread = new MyThread();
    thread.start();
    }
    }

    stop()方法以及作废,因为如果强制让线程停止有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现数据不一致的问题。

    7. 释放锁的不良后果

    使用stop()释放锁将会给数据造成不一致性的结果。如果出现这样的情况,程序处理的数据就有可能遭到破坏,最终导致程序执行的流程错误,一定要特别注意:

    public class SynchronizedObject {
    private String name = "a";
    private String password = "aa";

    public synchronized void printString(String name, String password){
    try {
    this.name = name;
    Thread.sleep(100000);
    this.password = password;
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getPassword() {
    return password;
    }

    public void setPassword(String password) {
    this.password = password;
    }
    }

    public class MyThread extends Thread {
    private SynchronizedObject synchronizedObject;
    public MyThread(SynchronizedObject synchronizedObject){
    this.synchronizedObject = synchronizedObject;
    }

    public void run(){
    synchronizedObject.printString("b", "bb");
    }
    }

    public class Run {
    public static void main(String args[]) throws InterruptedException {
    SynchronizedObject synchronizedObject = new SynchronizedObject();
    Thread thread = new MyThread(synchronizedObject);
    thread.start();
    Thread.sleep(500);
    thread.stop();
    System.out.println(synchronizedObject.getName() + " " + synchronizedObject.getPassword());
    }
    }

    输出结果:

    b  aa

    由于stop()方法以及在JDK中被标明为“过期/作废”的方法,显然它在功能上具有缺陷,所以不建议在程序张使用stop()方法。

    8. 使用return停止线程

    将方法interrupt()与return结合使用也能实现停止线程的效果:

    public class MyThread extends Thread {
    public void run(){
    while (true){
    if(this.isInterrupted()){
    System.out.println("线程被停止了!");
    return;
    }
    System.out.println("Time: " + System.currentTimeMillis());
    }
    }
    }

    public class Run {
    public static void main(String args[]) throws InterruptedException {
    Thread thread = new MyThread();
    thread.start();
    Thread.sleep(2000);
    thread.interrupt();
    }
    }

    输出结果:

    ...
    Time: 1467072288503
    Time: 1467072288503
    Time: 1467072288503
    线程被停止了!

    不过还是建议使用“抛异常”的方法来实现线程的停止,因为在catch块中还可以将异常向上抛,使线程停止事件得以传播。

    e3869c495bf2e00fb03875fc792c867a.png

    展开全文
  • small_rtos1.20.3

    2019-11-06 09:08:01
    而ucosII有源代码,但是它太大,又需要外部ram,所有函数又必须是入函数,用在51这类小片内RAM的单片机上有点勉强。于是,我借鉴ucosII和RTX Tiny编写了Small RTOS 51,虽然它为51系列编写,但是它还是比较容易...
  • MVC文件上传与下载

    2017-11-24 13:19:00
    想想自己从毕业到工作也有一年多,以前公司的任务的比较,项目中有的时候需要用到什么东西都去搜索一下,基础知识感觉还没有以前在学校中的好。最近开始写博客,真的是有一种心中有千言,下笔实无一字的感概,...

    想想自己从毕业到工作也有一年多,以前公司的任务的比较重,项目中有的时候需要用到什么东西都去搜索一下,基础知识感觉还没有以前在学校中的好。最近开始写博客,真的是有一种心中虽有千言,下笔实无一字的感概,本人不擅长理论,不擅长说教,不懂框架,现在写博客是即兴而言,均是自己的工作和个人学习中的感悟而写,本来以为写个文件上传下载两个小时之类博客神马的都全部搞定,实际耗费的时候三倍左右,不多说了,正题开始:

    1.上传文件File的Model建立

    FileName 文件名称   FileContent上传的文件以二进制的形式保存    FileExtName 文件后缀名   FilePath文件不保存在数据库时,存放一个相对路径

    复制代码
     1  public class File
     2     {
     3       
     4         [Key]
     5         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     6         public int ID { get; set; }
     7         public string FileName { get; set; }
     8         public byte[] FileContent { get; set; }
     9         public string FileExtName { get; set; }
    10         public DateTime UploadDate { get; set; }
    11         public string FilePath { get; set; }
    12     }
    复制代码

    2.文件上传及保存的两种方式

    前台页面的建立,这里如果你喜欢使用Razor的话直接使用Html.BeginForm就行.

    <form action="/File/UploadHanlder"  id="myForm" method="post"  enctype = "multipart/form-data">
        <input name="MyUploadile" type="file" />
        <input type="submit" value="提交"/>
    </form>

    文件上传之后保存在网站目录:

    复制代码
     1     if (Request.Files.Count == 0)
     2             {
     3                 return Content("请重新选择文件", "text/plain");
     4             }
     5             string path = AppDomain.CurrentDomain.BaseDirectory + "Upload\\";
     6             if (!Directory.Exists(path))
     7             {
     8                 Directory.CreateDirectory(path);
     9             }
    10             string fileName = Request.Files[0].FileName;
    11             string uploadPath = Path.GetFileName(fileName);
    12             Request.Files[0].SaveAs(Path.Combine(path, uploadPath));
    13             var file = new MvcFileUpload.Models.File
    14             {
    15                 FileName = GetFileNameOrSuffix(fileName, true),
    16                 FilePath = "/Upload/" + fileName,
    17                 FileExtName = GetFileNameOrSuffix(fileName, false),
    18                 UploadDate = DateTime.Now
    19             };
    20             dbConext.Files.Add(file);
    21             dbConext.SaveChanges();
    22             return Json(new { Flag = "1", Message = "文件上传成功" }, JsonRequestBehavior.AllowGet);
    复制代码

    文件名辅助方法:

    复制代码
     1 public  string   GetFileNameOrSuffix(string  name,bool  flag)
     2         {
     3            int  index= name.LastIndexOf(".");
     4            string[]  arr=name.Split(new  char[]{'.'},StringSplitOptions.RemoveEmptyEntries);
     5            if(flag)
     6            {
     7                return name.Substring(0, index);
     8              //  return   arr[0];
     9            }
    10            else  
    11            {
    12                return name.Substring(index+1, name.Length-index-1);
    13              //  return  arr[1];
    14            }
    15     
    16             
    17         }
    复制代码

    文件以二进制流的形式保存在数据库中:

    复制代码
     1    if (Request.Files.Count == 0)
     2             {
     3                 //return Json(new { Flag = "0", Message = "文件上传失败" }, JsonRequestBehavior.AllowGet);
     4                 return Content("没有文件", "text/plain");
     5             }
     6             int contentLength = Request.Files[0].ContentLength;
     7             Stream fileStream = Request.Files[0].InputStream;
     8             byte[] fileContent = new byte[contentLength];
     9             fileStream.Read(fileContent, 0, contentLength);
    10             string fileName = Request.Files[0].FileName;
    11             var file = new MvcFileUpload.Models.File
    12             {
    13                 FileName = GetFileNameOrSuffix(fileName, true),
    14                 FileContent = fileContent,
    15                 FileExtName = GetFileNameOrSuffix(fileName, false),
    16                 UploadDate = DateTime.Now
    17             };
    18             dbConext.Files.Add(file);
    19             dbConext.SaveChanges();
    20             //    return Content("文件上传成功", "text/plain");
    21             return Json(new { Flag = "1", Message = "文件上传成功" }, JsonRequestBehavior.AllowGet);
    复制代码

    好了一个简单的文件上传两种方式都保存方式都搞定了,如果我只写到这里的话网上到处都是,你没兴趣往下看,我不好意思写.各位看官继续看~

    3.表单的异步提交和Ajax.BeginForm()

    耗费时间最多的地方是在这里,你自己可以尝试一下当你使用Ajax.BeginForm提交表单的时候你明明传了文件发现结果确为空,Ajax不支持异步提交文件的方式,如果要实现文件的异步提交需要引用一个Jquery.form.js.

    (吐槽一两句,博客园有的博友好坑爹,我搜索的时候一不小心进去看到一个博友使用Jaqury.Form.js上面特意给了一个js下载,二话不说的下了之后发现很悲催,使用的时候有些方法一直没有执行到,怀疑自己的写错了,也没找到哪里有错,最后跑到因为官网下载一个最新版的js)

    Jquery.form.js的官网地址:http://www.malsup.com/jquery/form/,研究英文的你会发现比中文搜索的内容好的多,中文都是各种半瓶水的加工.

    前台页面如下:

    复制代码
     1 @{
     2     ViewBag.Title = "文件上传";
     3 }
     4 <script src="../../Scripts/jquery-1.7.1.js"></script>
     5 
     6 <script src="../../Scripts/jquery.form.js"></script>
     7 <script>
     8     (function () {
     9         $('#myForm').ajaxForm({
    10             target: '#outputdiv',
    11             beforeSend: function () {
    12                 alert("表单提交前");
    13             },
    14             target: '#outputdiv',
    15             success: function (data) {;
    16 
    17                     alert(data.Message);
    18             }
    19            
    20         }); 
    21 
    22     })();
    23 </script>
    24 <h1>上传文件</h1>
    25 <div id="outputdiv"> </div>
    26 <form action="/File/UploadHanlder"  id="myForm" method="post"  enctype = "multipart/form-data">
    27     <input name="MyUploadile" type="file" />
    28     <input type="submit" value="提交"/>
    29 </form>
    复制代码

    下载最新的插件,研究官网api的用法和Demo比你看其他人写的要快,后台处理的方法可以参考上面.

    4.图片,PDF文件预览和下载(针对的是保存在是网站目录下的文件)

    这个就是调用一下后台的数据在展示一下:

    后台处理方法:

      1 List<Models.File> list=dbConext.Files.Where(item=>item.FilePath!=null).ToList(); 2 return View(list); 

    前台页面展示:

    复制代码
     1 @{
     2     ViewBag.Title = "ShowData";
     3     List<string> typeList = new List<string>() { "png", "jpg", "jpeg" };
     4     List<string> otherList = new List<string>() { "xls", "doc", "docx","zip","rar","pdf"};
     5 }
     6 @model IEnumerable<MvcFileUpload.Models.File>
     7 <h2>图片</h2>
     8 @foreach (var item in Model)
     9 {
    10     if (typeList.Contains(item.FileExtName))
    11     {
    12         <img  src="@item.FilePath" alt="@item.FileName" height="200px" width="300px"/>
    13     }
    14 }
    15 <h2>其他文件</h2>
    16 @foreach (var item in Model)
    17 {
    18     if (otherList.Contains(item.FileExtName))
    19     {
    20     <a href="@item.FilePath" >@(item.FileName+"."+item.FileExtName)</a>
    21     }
    22 }
    复制代码

    5.二进制图片预览和文件下载

    后台控制器处理:

    复制代码
      public ActionResult ShowBinaryData()
            {
                var list = dbConext.Files.Where(item =>item.FilePath==null);
    
                return View(list);
            }
            public FileResult GetFile(int  id)
            {
                Models.File file = dbConext.Files.Where(item => item.ID == id).FirstOrDefault();
                List<string> typeList = new List<string>() { "png", "jpg", "jpeg" };
                List<string> otherList = new List<string>() { "xls", "doc", "docx", "zip","rar","pdf"};
                if (file==null)
                {
                    return null;  
                }
                if (typeList.Contains(file.FileExtName))
                {
                    return new FileContentResult(file.FileContent, "image/jpg");
                }
                if (otherList.Contains(file.FileExtName))
                {
                   return File(file.FileContent, "application/octet-stream",file.FileName+"."+file.FileExtName);
                }
                return null;
            }
    复制代码

     

    复制代码
     1 @{
     2     ViewBag.Title = "ShowData";
     3     List<string> typeList = new List<string>() { "png", "jpg", "jpeg" };
     4     List<string> otherList = new List<string>() { "xls", "doc", "docx","zip","rar","pdf"};
     5 }
     6 @model IEnumerable<MvcFileUpload.Models.File>
     7 <h2>图片</h2>
     8 @foreach (var item in Model)
     9 {
    10     if (typeList.Contains(item.FileExtName))
    11     {
    12         <img  src="/File/GetFile?Id=@item.ID" alt="@item.FileName" height="200px" width="300px"/>
    13     }
    14 }
    15 <h2>其他文件</h2>
    16 @foreach (var item in Model)
    17 {
    18     if (otherList.Contains(item.FileExtName))
    19     {
    20     <a href="/File/GetFile?Id=@item.ID">@(item.FileName+"."+item.FileExtName)</a>
    21     }
    22 }
    复制代码

     这里面因为存储的是二进制数据FileContentResult(file.FileContent, "image/jpg");如果是PDF,Word,xls的话,你需要给出一个下载名,不然下载出来的内容是没有格式的,File(file.FileContent, "application/octet-stream",file.FileName+"."+file.FileExtName).

    如果在上传的时候有限制的话加个配置<httpRuntime executionTimeout="5400" maxRequestLength="10485760" useFullyQualifiedRedirectUrl="false" />

    本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/3676597.html,如需转载请自行联系原作者

    展开全文
  • 众所周知,保证IT系统的... 企业市场竞争压力越来越大,也使CIO们迎来了严峻的考验,一方面是IT部门人员少、系统多、任务重的现状,另一方面是公司还要IT部门削减成本、并要消除由于缺乏内部控制和运作准则导致的混乱
  • 前段时间发放了学习资料给予自学java的同学们,自学好,但是架不住没有老师讲解侧点(实际上许多培训班的老师也是水分多多,甚至无实战经验),今天我就抽空把java零基础入门(六个月)的学习重点画出来,在不...
  • 大道至简2

    2015-06-19 16:05:00
    说到项目管理,虽然这不是一个简单的活儿但还是说一句欲戴皇冠必称其!有编程能力的不一定能掌控好公司的风帆,各尽所能是必要的,比尔盖茨把管理任务交给别人,而自己却进行技术上的攻坚,不可不谓之明智之举。...
  • small-rtos源码

    2011-03-10 14:20:09
    如在嵌入系统中使用C语言替代汇编...而ucosII有源代码,但是它太大,又需要外部ram,所有函数又必须是入函数,用在51这类小片内RAM的单片机上有点勉强。虽然它为51系列编写,但是它还是比较容易移植到其它CPU上。
  • smallRtos for C51

    2009-05-18 22:57:59
    而ucosII有源代码,但是它太大,又需要外部ram,所有函数又必须是入函数,用在51这类小片内RAM的单片机上有点勉强。于是,我借鉴ucosII和RTX Tiny编写了Small RTOS 51,虽然它为51系列编写,但是它还是比较容易...
  •  我在课堂教学上,能认真地完成教学任务,但碰到了不少问题。我发现现在的学生在变。在教学中,我发现现在的学生已与上几届不同,他们可能因其他学业的压力增加,他们对艺术学科越来越无所谓,学生在学习上心理...
  • small_rtos1.0

    2007-12-14 12:34:59
    而ucosII有源代码,但是它太大,又需要外部ram,所有函数又必须是入函数,用在51这类小片内RAM的单片机上有点勉强。于是,借鉴ucosII和RTX Tiny编写了Small RTOS 51,虽然它为51系列编写,但是它还是比较容易移植...
  • small_rtos1.12.1

    2007-12-14 12:38:21
    而ucosII有源代码,但是它太大,又需要外部ram,所有函数又必须是入函数,用在51这类小片内RAM的单片机上有点勉强。于是,我借鉴ucosII和RTX Tiny编写了Small RTOS 51,虽然它为51系列编写,但是它还是比较容易...
  • 快捷方式图标去箭头

    2017-02-03 10:11:21
    此法有不同形式,但无论是BAT命令还是其他不同高级语言编译的EXE,本质上是一样的。 使用高级语言只是换个形式使用命令, 其目的 一是隐藏代码不想公开,还有就是目的不纯 涉及灰色产业链,挂马带毒。 ~~~~~~~~~~...
  • <ul><li>setTimeout(callback, 0) // 延迟时间为 0 的定时器</li><li>Promise.resolve().then(callback) // 立刻决议的 Promise</li><li>requestAnimationFrame(callback) // 下次绘时执行</li></ul> 如果这些函数...
  • 本程序定位于学校或企业单位进行非严格要求的随机抽题考试,系统采用考试项目数据库独立方式,采用了ACCESS数据库,但能支持长期的考试要求,至少能支撑2000次以上5000人规模(非同时考试)的在线考试任务。...
  • (64KB)<END><br>108,MSDNWnd.zip 这是一个MSDN中的切分窗口的例子,不怎么样但已经完整展示了切分操作。对于初学者是一个很好的参考。(37KB)<END><br>109,rulers.zip 使用固定大小的切分窗口(上面、左边...
  •  对于一些重量级的工具,高手不常用,但一经使出也威力大于常人。如果让东方不败用剑,最厉害的剑术名家也会败得很难看。高手其实用过很多的重量级工具,而且深知其优缺点。所以使出来,就会把威力发挥到最大,而...
  • 大学物理-卢德馨序言

    2010-03-19 20:25:56
    承担了其中大学物理学的教学任务,致力于基础物理学课程的教学改革.他对 此深思熟虑,自有一套创新性的见解,而且有足够的能力和毅力,将这些概 念付诸实践.这本书就是他多年教学经验的结晶,既新颖可喜,又脚踏实地...
  •  点:规范研究——着重规定准则去帮助企业达到特定的目标。实证研究——着重叙述各种经济体制的实施方式(但无需说明它们应该如何实施)。 表2.1.1所列的传统经济学的各门课程,在某种程度上是重叠的。不仅...
  • 1 趋势报告 Trend Report 2019 人才流动 与薪酬趋势报告 1 企业需求不断演变,员工的招聘要求和管理模式也要实时更新。由于人才的培养周期长、企业内 部人才资本的存量不足或配置不完善、外部又面临着激烈的人才抢夺...
  • 设计任务书…………………………………………………2 第一部分 传动装置总体设计……………………………4 第二部分 V带设计………………………………………6 第三部分 各齿轮的设计计算……………………………9 第四...
  • 成复杂的任务。一个对象的生命期包括三个阶段:创建对象、对象的引用和释放对 象 。 1.8.3 创建对象 创建对象包括声明、实例化和初始化三方面的内容。通常的格式为 : 1. 声明对象 对象声明实际上是给对象命名,也称...

空空如也

空空如也

1 2
收藏数 30
精华内容 12
关键字:

任务虽重