java多线程编程_Thread类_线程状态的理解(1)
大家好,我是bug郭,一名双非科班的在校大学生。对C/JAVA、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流
作者简介:
- CSDN java领域新星创作者blog.csdn.net/bug…
- 掘金LV3用户 juejin.cn/user/bug…
- 阿里云社区专家博主,星级博主,developer.aliyun.com/bug…
- 华为云云享专家 bbs.huaweicloud.com/bug…
本节目标
-
学习
java
多线程编程! -
了解
java
中的Thread
类的基本使用! -
掌握
Thread
创建线程对象的5种方法 -
学习
Thread
类中的一些常用属性和方法!Thread
类我们知道操作系统中的线程是并发执行的!
而Thread
类是java
给我们提供的一个类,通过Thread
可以实现java
并发编程!Thread
类可以视为java
标准库提供的API
创建好的Thread
实例和操作系统的线程一一对应!!!Thread
是在java.lang
包下的类无需导入!!!了解并发编程
public class Thread_4 { public static void main(String[] args) { //自己创建的线程t1 Thread t1 = new Thread(()->{ while (true){ System.out.println("hello Thread!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); t1.start();//执行t1 while (true){ //主线程 main线程 一个java进程中自动创建了main线程!!! System.out.println("hello main"); try { Thread.sleep(1000); //睡眠1s 阻塞线程!在这1s不然上cpu }catch (InterruptedException e){ e.printStackTrace(); } } }
}
``
我们可以看到t1
线程和main
并发执行!这里的并发包括并发和并行!
我们也不知道cup
啥时候让这两个线程并发,啥时候并行!
这些都是操作系统的调度问题!!!
多线程优势
当我们要同时自增两数时,采用多线程编程和单线程编程又有啥区别呢,让我们看看下方代码就知道了!
//自增两数
public class Thread_8 {
private static final long count=100_0000_0000L;
public static void main(String[] args) throws InterruptedException{
concurrent();//多线程并行执行
serial(); //单线程串行执行
}
public static void concurrent() throws InterruptedException {
//多线程
long beign = System.nanoTime();//获取当前时间戳毫秒数
Thread t1 = new Thread(()->{
long a = 0;
for (int i = 0; i < count; i++) {
a++;
}
});
t1.start();
long b = 0;
for (int i = 0; i < count; i++) {
b++;
}
t1.join();
long end = System.nanoTime();//获取结束时间戳
System.out.println("并行:"+(end-beign));
}
public static void serial(){
long begin = System.nanoTime();
long a = 0;
for (int i = 0; i < count; i++) {
a++;
}
long b = 0;
for (int i = 0; i < count; i++) {
b++;
}
long end = System.nanoTime();
System.out.println("串行:"+(end-begin));
}
}
-
我们并不知道何时并发的两个线程是并行还是并发,这都是取决于线程的调度器的调取问题!
-
并发编程也不一定比串行快,如果自增的两数较小,创建变量的时间占据该线程执行的大部分时间,那么就达不到并发编程的优势!
-
是否采用多线程编程视情况而定,并非无脑多线程!
一个
java
进程中自动会创建一个main
线程!!!并在操作系统有对应该线程!
我们如何查看线程是否在操作系统中创建成功呢?
我们再jdk
中的lib
文件夹下打开jconsole.jar
文件便可以查看线程!!!
我们打开便可以看到我们创建的java
线程以及jvm
自带的一些线程!!!
创建Thread
实例
- 方法一
创建Thread
子类,重写run
方法
class Mythread extends Thread{
@Override
public void run() {//描述线程要执行的任务!
System.out.println("run");
}
}
public class Thread_1 {
public static void main(String[] args) {
Thread t1 = new Mythread();
t1.start();
}
}
这里的run
只是描述该线程需要执行那些任务!这只是创建了一个类! 线程的执行需要该线程实例执行start
方法!执行start
方法后操作系统才会创建对应的线程!
- 方法二
创建一个类实现Runnable
接口,重写run
方法,再将该类传参到创建Thread
对象的构造方法!
class MyRun implements Runnable{
@Override
public void run() {
//描述任务
System.out.println("实现Runnable接口创建线程!");
}
}
public class Thread_2 {
public static void main(String[] args) {
//将实现Runnable接口的对象传入Thread构造方法中!
Thread t1 = new Thread(new MyRun());
t1.start();//创建线程
}
}
我们来看看Thread
类的4个构造方法!
Thread()
无参构造
通过继承Thread
类
Thread(Runnable target);
传入Runnable
对象
Thread(String name);
给线程命名,便于程序员调试
- 方法三
Thread
匿名内部类
public class Thread_3 {
public static void main(String[] args) {
Thread t1 = new Thread(){
@Override
public void run() {
System.out.println("Thread匿名内部类!");
}
};
t1.start();
}
}
- 方法四
Runnable
接口匿名内部类
public class Thread_5 {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable匿名内部类!");
}
});
t1.start();
}
}
- 方法五
lambda
表达式
方法四/五的升级版!
public class Thread_6 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
System.out.println("lambda表达式!");
});
t1.start();
}
}
我们比较推荐使用Runnable
接口创建线程实例!
因为实现Runnable
接口,可以让线程和线程执行的任务,更好进行解耦!!!
简单说就是Runnable
方法创建线程实例, Runnable
可以将线程和线程任务分开!
我们实现一个Runnable
接口,我们只需要把入线程任务描述出来,不必关系那个线程执行该线程任务!,可能是线程,可能是进程,可能是协程,这些我们都不用关系!!!
- 点赞
- 收藏
- 关注作者
评论(0)