精华内容
下载资源
问答
  • 业务系统有多个线程在运行,为了防止线程挂掉,需要监控线程运行情况,在线程挂掉以后重新启动它。提示:先排错,再容错,这个方式只是用来兜底的。监控进程,遍历已经注册的线程,发现挂掉就重新创建并启动:import...

    业务系统有多个线程在运行,为了防止线程挂掉,需要监控线程运行情况,在线程挂掉以后重新启动它。

    提示:先排错,再容错,这个方式只是用来兜底的。

    监控进程,遍历已经注册的线程,发现挂掉就重新创建并启动:

    import java.util.HashMap;

    import java.util.Map;

    import java.util.Set;

    import java.util.TimerTask;

    /**

    * 监控线程 挂掉就重启

    */

    public class Monitor extends TimerTask {

    //线程列表

    final Mapthreads = new HashMap<>();

    @Override

    public void run() {

    // 遍历

    SetcentralNumbers = threads.keySet(); // map.keySet()返回key的集合

    for (String centralNumber : centralNumbers) {

    Thread thread = threads.get(centralNumber);

    if (!thread.isAlive()) {

    // 创建线程实体

    CentralServer centralServer = new CentralServer(centralNumber);

    // 创建线程

    Thread thead = new Thread(centralServer);

    // 注册监视器

    register(centralNumber, thead);

    // 开启

    thead.start();

    }

    }

    }

    // 注册监视器

    public void register(String centralNumber, Thread thread) {

    threads.put(centralNumber, thread);

    }

    }

    调用方法:

    public static void main(String[] args) {

    。。。。。。

    // 创建Timer实例

    Timer timer = new Timer();

    // 创建监视任务对象

    Monitor monitor = new Monitor();

    // 通过Timer定时定频率调用monitor的业务代码

    timer.schedule(monitor, 1000L, 1000*30L);

    //循环创建线程并注册监视器

    for (。。。 : 。。。) {

    // 线程实体

    CentralServer centralServer = new CentralServer(centralNumber);

    // 创建线程

    Thread thead = new Thread(centralServer);

    // 注册线程监视器

    monitor.register(centralNumber, thead);

    // 开启线程

    thead.start();

    }

    }

    展开全文
  • 业务系统有多个线程在运行,为了防止线程挂掉,需要监控线程运行情况,在线程挂掉以后重新启动它。 提示:先排错,再容错,这个方式只是用来兜底的。 监控进程,遍历已经注册的线程,发现挂掉就重新创建并启动: ...

    业务系统有多个线程在运行,为了防止线程挂掉,需要监控线程运行情况,在线程挂掉以后重新启动它。

    提示:先排错,再容错,这个方式只是用来兜底的。

    监控进程,遍历已经注册的线程,发现挂掉就重新创建并启动:

    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    import java.util.TimerTask;
    
    /**
     * 监控线程 挂掉就重启
     */
    
    public class Monitor extends TimerTask {
    
    	//线程列表
    	final Map<String, Thread> threads = new HashMap<>();
    
    	@Override
    	public void run() {
    		// 遍历
    		Set<String> centralNumbers = threads.keySet(); // map.keySet()返回key的集合
    		for (String centralNumber : centralNumbers) {
    			Thread thread = threads.get(centralNumber);
    			if (!thread.isAlive()) {
    				// 创建线程实体
    				CentralServer centralServer = new CentralServer(centralNumber);
    				// 创建线程
    				Thread thead = new Thread(centralServer);
    				// 注册监视器
    				register(centralNumber, thead);
    				// 开启
    				thead.start();
    			}
    		}
    	}
    
    	// 注册监视器
    	public void register(String centralNumber, Thread thread) {
    		threads.put(centralNumber, thread);
    	}
    }

    调用方法:

    public static void main(String[] args) {
    
            。。。。。。
    		// 创建Timer实例
            Timer timer = new Timer();
            // 创建监视任务对象
    		Monitor monitor = new Monitor(); 
    		// 通过Timer定时定频率调用monitor的业务代码
            timer.schedule(monitor, 1000L, 1000*30L);
    
            //循环创建线程并注册监视器
    		for (。。。 : 。。。) {
    
    			// 线程实体
    			CentralServer centralServer = new CentralServer(centralNumber);
    			// 创建线程
    			Thread thead = new Thread(centralServer);
    			// 注册线程监视器
    			monitor.register(centralNumber, thead);
    			// 开启线程
    			thead.start();
    		}
        }

     

    展开全文
  • java线程触发_java线程

    2021-03-14 15:35:54
    线程.状态新建状态(New):当用 new 操作符创建一个线程时, 例如 new Thread(r),线程还没有开始运行,此时线程处在新建状态。...当线程对象调用 start()方法即启动线程,start()方法创建线程运行的系统资源...

    线程.

    状态

    85f1edd7b46b17469ee2b9fea2f6a964.png

    新建状态(New):

    当用 new 操作符创建一个线程时, 例如 new Thread(r),线程还没有开始运行,此时

    线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码

    就绪状态(Runnable)

    一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的 start()方法。当线

    程对象调用 start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行

    run()方法。当 start()方法返回后,线程就处于就绪状态。

    处于就绪状态的线程并不一定立即运行 run()方法,线程还必须同其他线程竞争 CPU 时

    间,只有获得 CPU 时间才可以运行线程。因为在单 CPU 的计算机系统中,不可能同时运行

    多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。

    对多个处于就绪状态的线程是由 Java 运行时系统的线程调度程序(thread scheduler)来调度

    的。

    运行状态(Running)

    当线程获得 CPU 时间后,它才进入运行状态,真正开始执行 run()方法.

    阻塞状态(Blocked)

    线程运行过程中,可能由于各种原因进入阻塞状态:

    1>线程通过调用 sleep 方法进入睡眠状态;

    2>线程调用一个在 I/O 上被阻塞的操作,即该操作在输入输出操作完成之前不会返回

    到它的调用者;

    3>线程试图得到一个锁,而该锁正被其他线程持有;

    4>线程在等待某个触发条件;

    ......

    所谓阻塞状态是正在运行的线程没有运行结束,暂时让出 CPU,这时其他处于就绪状

    态的线程就可以获得 CPU 时间,进入运行状态。

    死亡状态(Dead)

    有两个原因会导致线程死亡:

    run 方法正常退出而自然死亡,

    一个未捕获的异常终止了 run 方法而使线程猝死。

    为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使

    用 isAlive 方法。如果是可运行或被阻塞,这个方法返回 true; 如果线程仍旧是 new 状态

    且不是可运行的, 或者线程死亡了,则返回 false

    新建线程的方法:

    1.继承Thread类实现多线程

    run()为线程类的核心方法,相当于主线程的main方法,是每个线程的入口

    一个线程调用 两次start()方法将会抛出线程状态异常,也就是的start()只可以被调用一次

    class Thread1 extends Thread{

    @Override

    public void run() {

    //迭代 循环

    for (int i = 0; i < 10; i++) {

    System.out.println(Thread.currentThread().getName()+"__"+i);

    }

    }

    }

    public class ThreadTest {

    public static void main(String[] args) {

    System.out.println("main start: "+Thread.currentThread().getName());

    for (int i = 0; i < 10; i++) {

    Thread1 thread1 =new Thread1();

    thread1.start();//多个跑道 并行

    }

    //main 不等了

    System.out.println(" main end ");

    }

    }

    2通过Runnable接口创建线程类

    定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

    创建 Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

    调用线程对象的start()方法来启动该线程。

    public class RunnableThreadTest implements Runnable {

    @Override

    public void run() {

    for (int i = 0; i < 10; i++) {

    System.out.println(Thread.currentThread().getName() + "__" + i);

    }

    }

    public static void main(String[] args) {

    System.out.println("main start: "+Thread.currentThread().getName());

    for (int i = 0; i < 5; i++) {

    RunnableThreadTest runnableThreadTest = new RunnableThreadTest();

    new Thread(runnableThreadTest,"线程"+i).start();

    }

    }

    }

    通过Callable和Future创建线程

    创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。

    public interface Callable

    {

    V call() throws Exception;

    }

    创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。(FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了Future和Runnable接口。)

    使用FutureTask对象作为Thread对象的target创建并启动新线程。

    调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

    public class CallableThreadTest implements Callable

    {

    public static void main(String[] args)

    {

    CallableThreadTest ctt = new CallableThreadTest();

    FutureTask ft = new FutureTask<>(ctt);

    for(int i = 0;i < 100;i++)

    {

    log.info(Thread.currentThread().getName()+" 的循环变量i的值"+i);

    if(i==20)

    {

    new Thread(ft,"有返回值的线程").start();

    }

    }

    try

    {

    log.info("子线程的返回值:"+ft.get());

    } catch (InterruptedException e)

    {

    e.printStackTrace();

    } catch (ExecutionException e)

    {

    e.printStackTrace();

    }

    }

    @Override

    public Integer call() throws Exception

    {

    int i = 0;

    for(;i<100;i++)

    {

    log.info(Thread.currentThread().getName()+" "+i);

    }

    return i;

    }

    }

    并行参数问题的解决

    ThreadLocal (线程本地变量) map

    新建ThreadLocal并重写initialValue() 重写initialValue 方法 否者对象为空

    调用方法(ThreadLocal定义的变量名)threadLocal.get();

    package com.testfan.thread;

    import java.util.HashMap;

    import java.util.Map;

    public class ThreadLocalMapTest {

    static ThreadLocal> threadLocal = new ThreadLocal>(){

    @Override

    protected Map initialValue() {

    return new HashMap();

    }

    };

    public static void main(String[] args) {

    threadLocal.get().put("1","11");

    dosomethings();

    new Thread(new Runnable() {

    @Override

    public void run() {

    threadLocal.get().put("1","22");

    dosomethings();

    }

    }).start();

    new Thread(new Runnable() {

    @Override

    public void run() {

    threadLocal.get().put("1","33");

    dosomethings();

    }

    }).start();

    }

    private static void dosomethings() {

    System.out.println(Thread.currentThread().getName() + " " +threadLocal.get());

    }

    }

    线程等待问题

    线程等待 join

    for (int i = 0; i < 10; i++) {

    Thread1 thread1 =new Thread1();

    thread1.start();//多个跑道 并行

    try {

    thread1.join();//线程等待

    } catch (InterruptedException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    sleep

    public static void main(String[] args) {

    System.out.println("main start: "+Thread.currentThread().getName());

    for (int i = 0; i < 10; i++) {

    Thread1 thread1 =new Thread1();

    thread1.start();//多个跑道 并行

    try {

    thread1.sleep(1);;//线程等待

    } catch (InterruptedException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    线程计数器

    public class ThreadDemo2 {

    public static void main(String[] args) throws InterruptedException {

    final CountDownLatch latch= new CountDownLatch(5);//使用java并发库concurrent

    //启用5个线程

    for(int i=1;i<=5;i++){

    new Thread(new Runnable(){

    public void run(){

    try {

    Thread.sleep(1000);

    } catch (Exception e) {

    e.printStackTrace();

    }

    System.out.println("子线程执行!");

    latch.countDown();//让latch中的数值减一

    }

    }).start();

    }

    //主线程

    latch.await();//阻塞当前线程直到latch中数值为零才执行

    System.out.println("主线程执行!");

    }

    }

    countDownLatch不可能重新初始化或者修改CountDownLatch对象内部计数器的值,一个线程调用countdown方法happen-before另外一个线程调用await方法

    线程池优化

    为什么用线程池:

    服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的。

    为每个请求创建一个新线程的开销很大;为每个请求创建新线程的服务器在创建和销毁线程上花费的时间和消耗的系统资源要比花在处理实际的用户请求的时间和资源更多。

    线程池为线程生命周期开销问题和资源不足问题提供了解决方案

    好处:

    在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。

    线程池的几种方法:

    https://www.cnblogs.com/aaron911/p/6213808.html

    第一种:定时任务(jenkines的定时任务)

    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

    实例:

    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

    scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

    @Override

    public void run() {

    System.out.println("111111");

    }

    },0,1,TimeUnit.SECONDS);//0代表延时多久 1代表多久执行一次,TimeUnit.SECONDS代表时间单位

    第二种:

    //可以最大开65536, 短任务

    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

    实例:

    for (int i = 0; i < 100000; i++) {

    final int index = i;

    //放了十个线程

    cachedThreadPool.execute(new Runnable() {

    public void run() {

    System.out.println(index+Thread.currentThread().getName());

    }

    });

    }

    fixedThreadPool.shutdown();

    第三种:

    //按照固定的数目

    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);//一次运行3个

    实例:

    for (int i = 0; i < 100; i++) {

    final int index = i;

    //放了十个线程

    fixedThreadPool.execute(new Runnable() {

    public void run() {

    System.out.println(index+Thread.currentThread().getName());

    }

    });

    }

    fixedThreadPool.shutdown();

    第四种:

    //默认一个

    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    实例:

    for (int i = 0; i < 100; i++) {

    final int index = i;

    //放了十个线程

    singleThreadExecutor.execute(new Runnable() {

    public void run() {

    System.out.println(index+Thread.currentThread().getName());

    }

    });

    }

    fixedThreadPool.shutdown();

    展开全文
  • java线程有6种状态:新建线程new,启动线程runnable,阻塞block,限时等待timed_waiting,等待线程waiting,终止线程terminated1.限时等待timed waiting :处于这种状态的线程不会被分配cpu执行时间。不过无须等待被其他...

    java线程有6种状态:

    新建线程new,启动线程runnable,阻塞block,限时等待timed_waiting,等待线程waiting,终止线程terminated

    1.限时等待timed waiting :处于这种状态的线程不会被分配cpu执行时间。不过无须等待被其他线程显式地唤醒,在一定时间之后它们会由系统自动唤醒。以下方法会让线程进行限时等待状态:

    a.  Thread.sleep()方法;

    b.  设置了Timeout参数的Object.wait()方法;

    c.  设置了Timeout参数的Thread.join()方法;

    d.  LockSupport.parNanos()方法;

    e. LockSupport.parkUntil()方法。

    2.无限期等待Waiting :处于这种状态的线程不会被分配cpu执行时间。它们要等待被其他线程显式地唤醒。

    以下方法会让线程进入无限期的等待状态:

    a.  没有设置Timeout参数的Object.wait()方法。

    b.  没有设置Timeout参数的Thread.join()方法。

    c.  LockSupport.park()方法。

    3.阻塞 Blocked :线程被阻塞了。"阻塞状态"与"等待状态"的区别,"阻塞状态"在等待着取到一个排他锁,这个事件将在另外一个线程放弃这个锁的时候发生。"等待状态"则是等待一段时间,或者唤醒动作的发生。在程序等待进入同步区域的时候,

    线程将进入这种状态。

    线程状态的转换如下:

    af49d76dcf0f59b98157959f6eff2cec.png

    参考资料:《深入理解java虚拟机》

    展开全文
  • Java线程

    2017-12-22 16:29:29
    但是守候线程却不独立于JVM,守候线程一般是由操作系统或者用户自己创建的。二、在调用start()方法之后:发生了一系列复杂的事情:在调用start()方法之后:发生了一系列复杂的事情:启动新的执行线程(具有新的
  • java-线程

    2018-05-01 22:11:47
    1.线程与进程 进程:一个程序的执行 线程:程序的单个顺序的流控制称为线程 ...线程启动后,系统自动调用run方法 3.创建线程 1.通过继承Thread类创建线程 2.通过向Thread()构造方法传递runable对象来创建线程class...
  • Java线程创建

    2014-02-28 11:47:00
    本文由广州疯狂软件java培训为... * 继承Thread类,在子类重写run()方法,创建子类对象调用start()方法启动线程系统自动调用run()方法。  *  *  *  * start方法会根据操作系统的不同,调用操作系统创建...
  • JAVA线程的创建

    2020-01-30 21:30:30
    线程是什么 进程:一个程序的执行叫做一个进程 线程:程序中单个顺序的流控制称为线程,一个进程中可以...线程体是用run()方法来实现的,线程启动后,系统自动调用run方法 例: 1、通过继承Thread类创建线程: 代码:...
  • 线程的常用方法1.start(): 线程调用该方法将启动线程,使之从新建状态进入就绪队列排队,一旦轮到它来享用CPU资源时,就可以脱离创建它的线程独立开始自己的生命周期了。2.run(): Thread类的run()方法与Runnable...
  • 一个网友正好需要这个东西,我就把几个技术整合到了一起。...把这个功能封装为一个Windows服务,在机器启动时可以自动启动 我们逐个看程序。 一、多线程下载 这个主要使用了HTTP协议里面的一个Range参数,
  • 一、Java设计之初——支持多线程1,Java在服务端开发语言中的地位——常年高居前三服务端开发经常会用到多线程,所以Java和多线程密不可分。...因为JVM自动启动线程/*** 即使在代码中我们不显示地创建线程,在运行ma...
  • 一.多线程的概念线程概念线程就是程序中单独顺序的流控制。线程本身不能运行,它只能用于程序中。说明:线程是程序内的顺序控制流,...当程序启动运行时,就自动产生一个线程,主方法main就在这个主线程上运行。我们...
  • JAVA线程学习

    2014-12-12 15:05:24
    java 线程有两类: 1、用户线程执行结束线程自动关闭 2、守护线程 ,由操作系统或用户创建,独立于jvm 直接调用run()并不能启动线程,必须要运行start(),执行一系统动作,才会启用新线程
  • java线程

    2015-05-03 21:01:50
    线程 【进程概念】指一个内存中运行的应用程序,每...(当所有的用户线程执行完毕的时候,jvm自动关闭,但是守候线程不独立于jvm。一般式由操作系统自己创建的) 【常见的方法】 l run() l start() l susp
  • 包括三个部分,实现时也是逐个做到的多线程的文件下载,HTTP协议 把这个功能做成一个HTTP的服务,侦听在某个端口上,方便非Java系统使用 把这个功能封装为一个Windows服务,在机器启动时可以自动启动我们逐个看...
  • 三步搞定,灰常简单。这个任务名称写的有点儿长,简单来说就是类似于linux系统下的守护...JAVA中其实进程的概念并不强烈,更多的接触到的是线程。而实现这个守护进程,其实用到的也是线程,用到一个工具:JavaService。
  • java 线程知识点

    2012-03-01 15:43:00
    进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。 进程中的多个线程共享进程的内存。 Java中,每个线程都有一个调用栈。 创建一个新的线程,就产生一个新的...
  • Java创建多线程

    2018-07-27 21:21:47
    继承Thread类创建多线程 ...在Thread类中,提供了一个start()方法用于启动线程线程启动后,系统自动调用run()方法。 class MyThread extends Thread { public void run() { while(true) { ...
  • java线程总结

    2016-04-24 23:06:11
    在一个操作系统中,每个独立执行的程序都可成为一个... 1,继承Thread类创建多线程,覆写Thread类的run()方法,start()方法用于启动线程,线程启动后,系统自动调用runU()方法;  public class Example02{  p
  • start()用来启动一个线程,当调用start()方法时,系统才会开启一个线程,通过Thead类中start()方法来启动线程处于就绪状态(可运行状态),此时并没有运行,一旦得到CPU时间片,就自动开始执行run()方法。...
  • JAVA线程】-大纲

    2021-03-06 17:21:18
    一、线程状态转换 新建(New) 创建后尚未启动。 可运行(Runnable) 可能正在运行,也可能正在等待 CPU 时间片。...无需等待其它线程显式地唤醒,在一定时间之后会被系统自动唤醒。 调用 Thread.sleep()
  • Java线程之线程池

    2019-09-30 21:53:59
    线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程自动启动这些任务。线程池线程都是后台线程。 2、线程池的优点 使用线程池可以有效控制系统中并发线程的数量,当系统包含大量并发线程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 427
精华内容 170
关键字:

java系统启动自动启动线程

java 订阅