JUC--创建线程

JUC–创建线程

背景

  • JUC–创建线程

  • 博主以黑马JUC进行学习

方法一,直接使用Thread

1
2
3
4
5
6
7
8
9
10
//创建线程对象
Thread t = new Thread(){
public void run(){
//要执行的任务
}
};
//给线程起个名字
t.setName("t1");
//启动线程
t.start();

方法二,使用Runnable配合Thread

  • 把【线程】和【任务】(要执行的代码)分开
    • Thread代表线程
    • Runnable可运行的任务(线程要执行的代码)
1
2
3
4
5
6
7
8
9
Runnable runnable = new Runnable(){
public void run(){
//要执行的任务
}
};
//创建线程对象
Thread t = new Thread(runnable);
//启动线程
t.start();
  • java8以后可以使用lambda精简代码(即带有@FunctionalInterface)
1
2
3
4
5
6
7
//创建任务对象
Runnable task2 = () -> {
log.debug("hello");
}
//参数1是任务对象;参数2是线程名字,推荐
Thread t2 = new Thread(task2,"t2");
t2.start();

方法一、二原理

  • 都是线程对象的run()
  • 方法一是把线程和任务合并在一起,方法二是把线程和任务分开
  • 用Runnable更容易与线程池等高级API配合
  • 用Runnable让任务类脱离了Thread继承体系,更灵活

方法三,FutureTask配合Thread

  • FutureTask能够接收Callable类型的参数,用来处理有返回结果的情况
1
2
3
4
5
6
7
8
9
10
11
12
13
//创建任务对象
FutureTask<Integer> task3 = new FutureTask<>(() -> {
log.debug("hello");
return 100;
});

//参数1是任务对象;参数2是线程名字
new Thread(task3,"t3").start();

//主线程阻塞,同步等待task执行完毕的结果
Integer result = task3.get();
log.debug("结果是:{}", result);

观察多个线程运行的现象

  • 交替执行
  • 谁先谁后,不由我们控制

查看线程进程的方法

  • windows

    • 任务管理器可以查看进程和线程数,也可以用来杀死进程
    • tasklist查看进程
    • tasklist杀死进程
  • Linux

    • ps -fe 查看所有进程
    • ps -fT -p 查看某个进程的所有线程
    • kill 杀死进程
    • top 按大写H切换是否显示线程
    • top -H -p 查看后果进程的所有线程
  • Java

    • jps命令查看所有Java进程

    • jstack 查看某个Java进程的所有线程状态

    • jconsole来查看某个Java进程中线程的运行情况(图形界面)

      • jconsole远程监控配置
      1
      2
      3
      4
      5
      6
      java -Djava.rmi.server.hostname=<ip地址> 
      -Dcom.sun.management.jmxremote
      -Dcom.sun.management.jmxremote.port=<连接端口>
      -Dcom.sun.management.jmxremote.ssl=<是否安全连接>
      -Dcom.sun.management.jmxremote.authenticate=<是否认证>
      java类名
      • 系统 hosts 配置
    • 认证访问配置(需认证时)

      • 复制 JRE 安装目录下的模板配置文件:

        cp $JAVA_HOME/jre/lib/management/jmxremote.password.template jmxremote.password`。

      • 修改权限:将 jmxremote.passwordjmxremote.access 文件权限修改为 600(仅文件所有者可读写,否则认证会失效)。

      • 连接配置:远程连接时填入用户名(默认有 controlRole 等角色),密码为配置文件中设置的对应密码。