Java基础-23总结多线程,线程实现Runnable接口,线程名字获取和设置,线程控制,线程安全,同步线程

本文详细介绍了Java中多线程的概念、实现方式(继承Thread类和实现Runnable接口)、线程名字的获取与设置、线程调度与优先级、线程控制(休眠、加入、礼让)以及线程安全问题的产生和解决方案,包括同步代码块和同步方法。通过实例展示了如何避免并发问题,提升应用程序的使用率。
摘要由CSDN通过智能技术生成

你需要的是什么,直接评论留言。

获取更多资源加微信公众号“Java帮帮” (是公众号,不是微信好友哦)

还有“Java帮帮”今日头条号,技术文章与新闻,每日更新,欢迎阅读

学习交流请加Java帮帮交流QQ群553841695

分享是一种美德,分享更快乐!


1:多线程(理解)

(1)多线程:一个应用程序有多条执行路径

进程:正在执行的应用程序

线程:进程的执行单元,执行路径

单线程:一个应用程序只有一条执行路径

多线程:一个应用程序有多条执行路径

多进程的意义?

提高CPU的使用率

多线程的意义?

提高应用程序的使用率

(2)Java程序的运行原理及JVM的启动是多线程的吗?

A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程。

B:JVM的启动是多线程的,因为它最低有两个线程启动了,主线程和垃圾回收线程。


package cn.itcast_01;

/*

 * 进程:

 * 正在运行的程序,是系统进行资源分配和调用的独立单位。

 * 每一个进程都有它自己的内存空间和系统资源。

 * 线程:

 * 是进程中的单个顺序控制流,是一条执行路径

 * 一个进程如果只有一条执行路径,则称为单线程程序。

 * 一个进程如果有多条执行路径,则称为多线程程序。

 *

 *  举例:

 *   扫雷程序,迅雷下载

 *  

 *  大家注意两个词汇的区别:并行和并发。

 * 前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。

 * 后者是物理上同时发生,指在某一个时间点同时运行多个程序。

 *

 * Java程序的运行原理:

 *  由java命令启动JVM,JVM启动就相当于启动了一个进程。

 *  接着有该进程创建了一个主线程去调用main方法。

 * 

 * 思考题:

 *  jvm虚拟机的启动是单线程的还是多线程的?

 *  多线程的。

 *  原因是垃圾回收线程也要先启动,否则很容易会出现内存溢出。

 *  现在的垃圾回收线程加上前面的主线程,最低启动了两个线程,所以,jvm的启动其实是多线程的。

 */

public class MyThreadDemo {

public static void main(String[] args) {

System.out.println("hello");

new Object();

new Object();

new Object();

new Object();

//...

System.out.println("world");

}

}


(3)多线程的实现方案(自己补齐步骤及代码 掌握)

A:继承Thread类


package cn.itcast_02;(1)


/*

 * 该类要重写run()方法,为什么呢?

 * 不是类中的所有代码都需要被线程执行的。

 * 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。

 */

public class MyThread extends Thread {


@Override

public void run() {

// 自己写代码

// System.out.println("好好学习,天天向上");

// 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进

for (int x = 0; x < 200; x++) {

System.out.println(x);

}

}


}

package cn.itcast_02;(2)


/*

 * 需求:我们要实现多线程的程序。

 * 如何实现呢?

 *  由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来。

 *  而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。

 *  Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序。

 *  但是呢?Java可以去调用C/C++写好的程序来实现多线程程序。

 *  由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西,

 *  然后提供一些类供我们使用。我们就可以实现多线程程序了。

 * 那么Java提供的类是什么呢?

 *  Thread

 *  通过查看API,我们知道了有2中方式实现多线程程序。

 * 

 * 方式1:继承Thread类。

 * 步骤

 *  A:自定义类MyThread继承Thread类。

 *  B:MyThread类里面重写run()?

 *  为什么是run()方法呢?

 *  C:创建对象

 *  D:启动线程

 */

public class MyThreadDemo {

public static void main(String[] args) {

// 创建线程对象

// MyThread my = new MyThread();

// // 启动线程

// my.run();

// my.run();

// 调用run()方法为什么是单线程的呢?

// 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果

// 要想看到多线程的效果,就必须说说另一个方法:start()

// 面试题:run()和start()的区别?

// run():仅仅是封装被线程执行的代码,直接调用是普通方法

// start():首先启动了线程,然后再由jvm去调用该线程的run()方法。

// MyThread my = new MyThread();

// my.start();

// // IllegalThreadStateException:非法的线程状态异常

// // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。

// my.start();


// 创建两个线程对象

MyThread my1 = new MyThread();

MyThread my2 = new MyThread();


my1.start();

my2.start();

}

}


B:实现Runnable接口


package cn.itcast_05;(1)


public class MyRunnable implements Runnable {


@Override

public void run() {

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

// 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用

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

}

}

}

package cn.itcast_05;(2)


/*

 * 方式2:实现Runnable接口

 * 步骤:

 *  A:自定义类MyRunnable实现Runnable接口

 *  B:重写run()方法

 *  C:创建MyRunnable类的对象

 *  D:创建Thread类的对象,并把C步骤的对象作为构造参数传递

 */

public class MyRunnableDemo {

public static void main(String[] args) {

// 创建MyRunnable类的对象

MyRunnable my = new MyRunnable();


// 创建Thread类的对象,并把C步骤的对象作为构造参数传递

// Thread(Runnable target)

// Thread t1 = new Thread(my);

// Thread t2 = new Thread(my);

// t1.setName("林青霞");

// t2.setName("刘意");


// Thread(Runnable target, String name)

Thread t1 = new Thread(my, "林青霞");

Thread t2 = new Thread(my, "刘意");


t1.start();

t2.start();

}

}

(4)线程的名字获取与设置



package cn.itcast_03;(1)   


public class MyThread extends Thread {


public MyThread() {

}

public MyThread(String name){

super(name);

}


@Override

public void run() {

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

System.out.println(getName() + ":" + x);

}

}

}


package cn.itcast_03;(2)   


/*

 * 如何获取线程对象的名称呢?

 * public final String getName():获取线程的名称。

 * 如何设置线程对象的名称呢?

 * public final void setName(String name):设置线程的名称

 * 

 * 针对不是Thread类的子类中如何获取线程对象名称呢?

 * public static Thread currentThread():返回当前正在执行的线程对象

 * Thread.currentThread().getName()

 */

public class MyThreadDemo {

public static void main(String[] args) {

// 创建线程对象

//无参构造+setXxx()

// MyThread my1 = new MyThread();

// MyThread my2 = new MyThread();

// //调用方法设置名称

// my1.setName("林青霞");

// my2.setName("刘意");

// my1.start();

// my2.start();

//带参构造方法给线程起名字

// MyThread my1 = new MyThread("林青霞");

// MyThread my2 = new MyThread("刘意");

// my1.start();

// my2.start();

//我要获取main方法所在的线程对象的名称,该怎么办呢?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java帮帮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值