本文由 ImportNew - liken 翻译自 Journaldev.   Java线程是执行某些任务的轻量级进程.Java通过Thread类提供多线程支持,应用可以创建并发执行的多个线程. 应用中有两类线程——用户线程和守护线程.当启动应用时,main线程是创建的第一个用户线程,我们可以创建多个用户线程和守护线程.当所有用户进程执行完毕时,JVM终止程序. 可以对不同的线程设置不同的属性,但并不保证高优先级的线程在低优先级线程之前执行.线程调度器是操作系统的部分实现,当一个线程启动后,它的…
在Java多线程之中,Callable和Future的使用时非常广泛的.在之前的文章中,我们了解了关于Java线程池基础的一些内容,知道如何提交Runnable的任务.但是,Runnable的任务是无法有返回值,也不能抛出异常的.而有些时候,我们希望一个线程能够有一些返回值.在Java 5中,引入了java.util.concurrent.Callable接口,这个接口很类似于Runnable接口,但是可以返回一个对象,或者抛出异常. Java Callable Java的Callable接口使…
Java 线程池管理多个工作线程,其中包含了一个队列,包含着所有等待被执行的任务.开发者可以通过使用ThreadPoolExecutor来在Java中创建线程池. 线程池是Java中多线程的一个重要概念,因为通过Thread模型来控制多线程是非常麻烦以及易错的一个过程.过多的释放线程会造成线程调度的变慢以及过度的消耗内存.而频繁的创建线程,也没有很好的复用线程,所以有了线程池的概念.Java中的线程池就是ExecutorService. 其中包含了一些基本的关闭,执行等功能 ExecutorSe…
线程安全在Java中是一个很重要的课题.Java提供的多线程环境支持使用Java线程.我们都知道多线程共享一些对象实例的话,可能会在读取和更新共享数据的事后产生数据不一致问题. 线程安全 之所以会产生数据的不一致问题,是因为更新实例变量等类似的行为并非是原子操作.这类操作会有三个步骤: 读取当前的值 做一些必要的操作来获取更新的值 将更新的值写会变量之中 我们来看如下程序中多线程如何更新和共享数据: package com.sapphire.threads; public class Threa…
Java 线程是一个轻量级执行任务的处理单元.Java提供了Thread类来支持多线程,开发者在应用中可以创建多个线程来支持并发执行任务. 在应用中存在两种类型的线程,用户线程和守护线程.当我们启动应用的时候,main函数是第一个启动的用户线程,开发者可以在之后自由的创建用户线程.当所有的线程执行完毕,JVM会终结掉程序. 开发者也可以配置不同线程的优先级,但是这并不代表更高优先级的线程会比低优先级的线程先执行.因为线程的执行取决于线程调度器,而线程调度器的实现是基于操作系统的.当一个线程启动后…
Java是一门支持多线程的编程语言! 什么是进程? 计算机中内存.处理器.IO等资源操作都要为进程进行服务. 一个进程上可以创建多个线程,线程比进程更快的处理单元,而且所占用的资源也小,多线程的应用也是性能最高的. Java的多线程实现:(三种方式) 在Java中实现多线程有两种途径: 1.继承Thread类 2.实现Runnable接口 3.实现Callable接口 继承Thread类: class MyThread extends Thread { //继承Thread 即 多线程类[线程操…
Java的Thread Dump就是列出JVM中所有激活状态的线程. Java Thread Dump Java Thread Dump在分析应用性能瓶颈和死锁的时候,是非常有效的. 下面将介绍多种不同的方式来获取Java程序的Thread Dump信息.这些指令在*nix型的操作系统下是有效的,但是在Windows下面,采取的方式会有一些不同.(主要是Pid信息获取不太一致,可通过任务管理器获取) VisualVM Profiler:如果开发者需要分析程序变慢的原因,那么必然要使用profil…
这次讨论的是Java的BlockingQueue,java.util.concurrent.BlockingQueue是一个Java的队列接口,支持一系列操作,比如,在获取和移除对象的时候如果队列为空会来等待队列变成非空的,而当队列满了的时候,插入元素会等待队列中的元素被移除,保证队列有空余的空间. Java的BlockingQueue是不能接受null的值,如果传入null将会跑出NullPointerException的. 如果看到JDK的源码的话,其中会包含一个非空检查的方法 /** *…
java创建线程两种方式: 1.继承Thread创建线程 /** * Created by lsf on 16/4/18. */ class NewThread extends Thread { NewThread(){ super(); //创建线程 start(); //启动线程 } public void run() { long starttime = System.currentTimeMillis(); System.out.println("child thread..."…
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hljs-comment, .hljs-template_comment, .diff .hljs-header, .hljs-javadoc { color: #998; font-style: italic; } .hljs-keyword, .css .rule .hljs-keyword, .h…
当开发者在应用中使用了并发来提升性能的同时,开发者也需要注意线程之间有可能会相互阻塞.当整个应用执行的速度比预期要慢的时候,也就是应用没有按照预期的执行时间执行完毕.在本章中,我们来需要仔细分析可能会影响应用多线程的活性问题. 死锁 死锁的概念在软件开发者中已经广为熟知了,甚至普通的计算机用户也会经常使用这个概念,尽管不是在正确的状况下使用.严格来说,死锁意味着两个或者更多线程在等待另一个线程释放其锁定的资源,而请求资源的线程本身也锁定了对方线程所请求的资源.如下: Thread 1: lock…
Java中的死锁指的就是一种多于两个线程永远阻塞的特殊状况.Java中的死锁状态至少需要多于两个线程以及资源的时候才会产生.这里,我写了一个产生死锁的程序,并且讲下如何分析死锁. 首先来看一下产生死锁的程序: package com.sapphire.threads; public class ThreadDeadlock { public static void main(String[] args) throws InterruptedException { Object obj1 = ne…
Java对象中的wait,notify以及notifyAll方法 在Java的Object类中包含了3个final的方法,这三个方法允许线程来交流资源是否被锁定.这三个方法就是wait(),notify()以及notifyAll(). 在对象上调用这三个方法的线程需要包含一个对象监视器(锁),否则就会抛出java.lang.IllegalMonitorStateException异常. wait方法 对象的wait方法有三个,一个是令对象等待任何线程来调用notify或者notifyAll方法来…
java的线程之间资源共享,所以会出现线程同步问题(即,线程安全) 一.线程创建: 方式①:extends java.lang.Thread,重写run(),run方法里是开启线程后要做的事..start()启动线程,执行run()里的程序. 方式②:implements java.lang.runnable,实现run(); 然后new Thread(implements产生的线程); 调用.start()启动线程 Thread的方法: .run() 定义线程要做的事 .start() 启动线…
Java中的java.util.Timer是一个工具类,可以用于调度一个线程在将来的某一个时刻执行特定的任务.Java Timer类可以将一个任务定时执行一次,或者是以后以每隔一定的时间间隔来触发一次. Java TimerTask java.util.TimerTask是一个抽象类,也同时实现了Runnable接口的.我们可以继承这个类来创建我们自己的TimerTask之后由Timer来调度. Java Timer举例 Java Timer类是线程安全的,多个线程可以共享一个Timer对象而不…
Java中的ThreadLocal是用来创建线程本地变量用的.我们都知道,访问某个对象的所有线程都是能够共享对象的状态的,所以这个对象状态就不是线程安全的.开发者可以通过使用同步来保证线程安全,但是如果不希望使用同步的话,我们也可以使用ThreadLocal变量. Java ThreadLocal 其实每个线程都有自己的ThreadLocal变量,并且这个变量可以通过get()和set()方法来获取默认值,或者修改其值. ThreadLocal实例可以配置为静态私有变量来关联线程的状态. Jav…
当我们在Java中创建线程的时候,这个线程在默认的情况下是一个用户线程,并且,如果这个线程在运行,那么JVM就不会终结这个应用.和用户线程不同,当一个线程被标记为守护线程的时候,JVM在用户线程结束的时候,是不会持续等待守护线程结束的,而是直接结束程序,并且结束程序中相关的守护线程. Thread.setDaemon(true)方法可以用来将线程置为守护线程,参考下面的例子: package com.sapphire.threads; public class JavaDaemonThread…
单例模式是最广泛使用的创建模式之一.在现实世界之中,诸如Databae的连接或者是企业信息系统(EIS)等,通常其创建都是受到限制的,应该尽量复用已存在对象而不是频繁创建销毁.为了达到这个目的,开发者通常会通过实现单例模式来创建一个wrapper类,来封装资源,限制其运行时所创建对象的个数. 单例中的线程安全 总的来说,开发者一般会按照如下的方式来创建单例的类: 使用私有构造函数来避免其它外部引用通过new的方式来创建新的对象引用. 声明一个该类的私有静态变量为实例. 提供一个公有的静态方法来返…
曾经有一个比较有趣的面试问题,那就是,关于使用synchronized关键字,是用在方法上面尾号,还是用在一个代码块上面为好? 答案就是使用锁定代码块为更好.因为这样不会锁定对象.当synchronized关键字在实例方法的上面时,线程对于该方法的访问会直接锁定整个对象,参考如下代码: class Sync { public synchronized void syncMethod() { System.out.println("Sync Method Executed"); } pu…
作为Java的开发者,在运行程序的时候会碰到主线程抛异常的情况.如果开发者使用Java的IDE比如Eclipse或者Intellij IDEA的话,可能是不需要直接面对这个问提的,因为IDE会处理运行类来处理这些问题. 下面将描述一些在命令行模式下运行Java程序可能会碰到的异常. java.lang.UnsupportedClassVersionError 这个异常时因为你的Java类是由另一个其他版本的JDK编译的,但是却在这个版本的命令行下尝试执行.参考下面的例子: package com…
package org.jimmy.searchfile20180807.main; public class ThreadMain implements Runnable{ private int taskNum; private String searchDirPath; private String keyWords; public ThreadMain(int taskNum, String searchDirPath, String keyWords){ this.taskNum =…
文件读取和操作类 import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; public class Test3 { private String keyWords; public Test3(String keyWords){ this.keyWords = keyWords; } //计算文件数量 public static int count = 0; //搜索后查询到的文件路…
当你需要使用Java线程在多线程环境下进行编程时,理解Java的线程周期与线程的状态是非常重要的.通过实现Runnale接口或者继承Thread类,我们可以创建线程,为了启动一个线程,我们需要创建一个Thread对象,并且调用它的start()方法,以便以线程的方式来执行run()方法. Java中的线程生命周期 下面的图展示在Java中线程的不同状态,我们可以创建一个Java线程,并调用start()方法来启动它,但是线程的状态是如何从Running变为Blocked,这依赖与操作系统实现的线…
Java线程面试题 Top 50 原文链接:http://www.importnew.com/12773.html   本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎加入Java小组.转载请参见文章末尾的要求. 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.大多数待遇丰厚的Java开发职位都要求开发者精通多线程技术并且有丰富的Java程序开发.调试.优化经验,所以…
JAVA之旅(十一)--RuntimeException,异常的总结,Package,jar包,多程序概述 继续JAVA之旅 一.RuntimeException 在Exception种有一个特殊的子类异常RuntimeException,翻译过来就是运行异常,如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过,如果在函数上声明了该异常,调用者可以不用处理,编译一样通过 之所以不用函数声明,是因为不需要让调用调用者处理,当然该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况…
一.总览 线程池类ThreadPoolExecutor的相关类需要先了解: (图片来自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8%A7%88) Executor:位于最顶层,只有一个 execute(Runnable runnable) 方法,用于提交任务. ExecutorService :在 Executor 接口的基础上添加了很多的接口方法,提交任务,获取结果,关闭线程池. AbstractExecutorService…
Java线程(Java Thread)是执行某些任务的一种轻量级进程.Java中的Thread类提供了多线程(multi-threading)功能,应用程序能够创建多个线程并同一时候执行. 在一个应用程序中,一般会有两种类型的线程-用户线程(user thread)和守护线程(daemon thread).当我们启动引用程序时,首先创建用户线程main,我们能够创建多个用户线程和守护线程.当全部的用户线程都运行完成时,JVM就会终止程序. 对不同的线程,我们能够设置对应的优先级,但并不意味着高优…
JAVA线程队列BlockingQueue 介绍 BlockingQueue阻塞队列,顾名思义,首先它是一个队列,通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出. 常用的队列主要有以下两种:(当然通过不同的实现方式,还可以延伸出很多不同类型的队列,DelayQueue就是其中的一种) 先进先出(FIFO):先插入的队列的元素也最先出队列,类似于排队的功能.从某种程度上来说这种队列也体现了一种公平性. 后进先出(LIFO):后插入队列的元素最先出队列,这种队列优先处理最近发生的事…
下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的Worker,线程池底层实现原理 6. 线程池工具类如Executors等 7. 如何停止一个线程(含代码),源码查看Thread.interrupted()和Thread.currentThread().isInterrupted()区别 8. 如何合理的配置 Java 线程池?如 CPU 密集型…
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行的代码 继承java.lang.Thread创建线程 public class Test1 { public static void main(String[] args){ System.out.println("现在是主线程: "+Thread.currentThread()); //…