Java中的线程

1.1 特征和状态
  1. 所有的Java程序中,不论并发与否,都有一个名为主线程的Thread对象。执行该程序时,Java虚拟机(JVM)将创建一个新的Thread并在该线程中执行main()方法。这是非并发应用程序中唯一的线程,也是并发程序中的第一个线程。

  2. Java中的线程共享应用程序中的所有资源,包括内存和打开文件,快速而简单共享信息。但是必须使用同步避免数据竞争。

  3. Java中的所有线程都有一个优先级,这个整数值介于Thread.MIN_PRIORITY(1)和Thread.MAX_PRIORITY(10)之间,默认优先级是Thread.NORM_PRIORITY(5)。线程的执行顺序并没有保证,通常,较高优先级的线程将在较低的优先级的线程之前执行。

  4. 在Java中,可以创建两种线程:守护线程和非守护线程。区别:在于他们如何影响程序的结束
    java程序结束执行过程的情形:

    1、程序执行Runtime类的exit()方法,而且用户有权执行该方法。
    2、应用程序的所有非守护线程均已结束执行,无论是否有正在运行的守护线程

    守护线程通常作为垃圾回收器或缓存管理器的应用程序中,执行辅助任务。在线程start之前调用isDeamon()方法
    检查线程是否为守护线程,也可以使用setDaemon()方法将某个线程确立为守护线程。

  5. Thread.States 类中定义线程的状态如下:

    NEW:Thread 对象已经创建,但是还没有开始执行。
    RUNNABLE:Thread 对象正在Java 虚拟机 中运行。
    BLOCKED: Thread 对象正在等待锁定。
    WAITING:Thread 对象正在等待另一个线程的动作
    TIME_WAITING:Thread 对象正在 等待另一个线程的操作,但是有时间的限制。
    TERMINATED: Thread 对象已经完成了执行。

    getState()方法获取Thread对象的状态,可以直接更改线程的状态。
    在给定时间内,线程只能处于一个状态。这些状态是JVM使用的状态,不能映射到操作系统状态。
    线程状态的源码:
    在这里插入图片描述

1.2 Runnable 和 Thread

简单的实现

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        while (true){
            System.out.println(Thread.currentThread().getName() + " run " );
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

public class MyThread extends Thread {
    @Override
    public void run() {
        while (true){
            System.out.println(Thread.currentThread().getName() + "运行了" );
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        MyThread thread = new MyThread();
        MyThread thread1 = new MyThread();
        thread.start();
        thread1.start();
    }
}

Runnale接口只定义了一种方法:run()方法。这是每个线程的主方法,当执行start()方法启动新线程时,它将调用run()方法。

Thread类其他常用方法:

  • 获取和设置Thread对象的信息方法:

    1、getId():该方法返回Thread对象的标识符。该标识符是线程创建是分配的一个正整数。在线程的整个生命周期中是唯一且无法改变的。
    2、getName()/setName():这两种方法允许你获取或设置Thread对象的名称。这个名称是一个String对象,也可以在Thread类的构造函数中建立。
    3、getPriority()/setPriority(): 你可以使用者两种方法获取或设置Thread对象的优先级。
    4、isDaemon()/setDaemon() : 这两种方法允许你获取或建立Thread对象的守护条件。
    5、getState() : 该方法返回Thread 对象的状态。

  • interrupt() : 中断目标线程,给目标线程发送一个中断信号,线程别打上中断标记。

  • interrupted():判断目标线程是否被中断,但是将清除线程的中断标记。

  • isinterrupted():判断目标线程是否被中断,不会清除中断标记。

  • sleep(long ms):该方法将线程的执行暂停ms时间。

  • join():暂停线程的执行,直到调用该方法的线程执行结束为止。可以使用该方法等待另一个Thread对象结束。

  • setUncaughtExceptionHandler():当线程执行出现未校验异常时,该方法用于建立未校验异常的控制器。

  • currentThread():Thread类的静态方法,返回实际执行该代码的Thread对象。

join示例程序:

public class MyJoin extends Thread {

    @Override
    public void run() {
        int size = 100;
        for (int i = 0; i < size; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }
    }
    public static void main(String[] args) throws InterruptedException {

        MyJoin myJoin = new MyJoin();
        myJoin.setName("线程一");
        MyJoin myJoin2 = new MyJoin();
        myJoin2.setName("线程二");

        myJoin.start();
        myJoin.join();
        myJoin2.start();
        myJoin2.join();

        System.out.println("main线程 - 执行完成");
    }
}
1.3 Callable

Callable 接口是一个与Runnanle 接口非常相似的接口。Callable接口的主要特征如下。

  • 接口。有简单类型参数,与call() 方法的返回类型相对应。
  • 声明了call()方法。执行器运行任务,该方法会被执行器执行。它必须返回声明中指定类型的对象。
  • call() 方法可以抛出任何一种校验异常。可以实现自己的执行器并重载afterExecute()方法来处理这些异常、
package com.lagou.demo1;

import java.util.concurrent.*;

/**
 * @author xibanqiu
 * created by sheting on 2021/4/19
 */
public class MyCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        Thread.sleep(5000);
        return "hello world call() invoked!!";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable myCallable = new MyCallable();
//        FutureTask<String> futureTask = new FutureTask<String>(myCallable) ;
//        new Thread(futureTask).start();
//        String result = futureTask.get();
//        System.out.println(result);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5,5,1,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10)){
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
            }
        };
//        Future<String> future = executor.submit(myCallable);
        Future<?> future = executor.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(1111);
            }
        });
        String s = (String) future.get();
        System.out.println(s);
        executor.shutdown();
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值