首页 > 其他分享 >多线程_小记

多线程_小记

时间:2023-04-12 10:09:12浏览次数:39  
标签:Thread void 线程 new 多线程 public 小记


程序进入内存中运行就变成一个进程,进程具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位。

进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。(进程是资源分配的最小单位)
  线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)
  线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
  多进程是指操作系统能同时运行多个任务(程序)。
  多线程是指在同一程序中有多个顺序流在执行。
在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口.(其实准确来讲,应该有三种,还有一种是实现Callable接口,并与Future、线程池结合使用

多进程的目的是提高CPU的使用率,提高工作效率,多个工作可以同时进行。
在一个进程里,会有多个线程并发执行抢夺cpu的使用权,抢夺概率是随机的。。

注:JVM也是多线程程序,因为其自带垃圾回收器,确保程序不会轻易的造成内存溢出看,所以JVM至少开启两条线程。一是程序会执行main主线程;二是垃圾回收器线程的运行确保程序不会内存异常。


重点:如何实现多线程程序?
* 要实现多线程程序,必须创建一个进程,
* 创建进程需要调用系统资源进行创建,但是Java语言是不能直接调用系统资源
* C/C++语言是可以创建系统资源,然后使用Java语言掉C/C++已经封装好的东西,

多线程程序实现方式1:
1)自定一个类:MyThread 继承自Thread类
2)在MyThread类中重写Thread类中的run()
3)在主线程中,创建该类的实例对象,启动线程

测试类
package Day20_DuoJinCheng;
/**
 * @author Aoman_Hao
 */
public class Test1 {

    public static void main(String[] args) {
        //创建进程
        //无参构造
        UseThread U1 = new UseThread();
        U1.setName("U1");

        //有参构造
        UseThread U2 = new UseThread("U2");

        U1.start();
        U2.start();

    }

}
对象类:
package Day20_DuoJinCheng;
/**
 * @author Aoman_Hao
 */
public class UseThread extends Thread {

    //无参构造
    public UseThread() {
        super();
    }

    //有参构造
    public UseThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for(int i=1;i<20;i++){
            System.out.println("进程"+Thread.currentThread().getName()+"的数字:"+i);
        }
    }
}

输出:进程U2的数字:1
进程U1的数字:1
进程U2的数字:2
进程U1的数字:2
进程U2的数字:3
进程U1的数字:3
进程U2的数字:4
进程U1的数字:4
进程U1的数字:5
进程U1的数字:6
进程U1的数字:7
进程U1的数字:8
进程U1的数字:9
进程U1的数字:10
进程U1的数字:11
进程U1的数字:12
进程U1的数字:13
进程U1的数字:14
进程U1的数字:15
进程U1的数字:16
进程U1的数字:17
进程U1的数字:18
进程U1的数字:19
进程U2的数字:5
进程U2的数字:6
进程U2的数字:7
进程U2的数字:8
进程U2的数字:9
进程U2的数字:10
进程U2的数字:11
进程U2的数字:12
进程U2的数字:13
进程U2的数字:14
进程U2的数字:15
进程U2的数字:16
进程U2的数字:17
进程U2的数字:18
进程U2的数字:19

多线程构建方法2:
1)自定义一个类MyRunnable,该类实现Runnable接口
2)实现该接口中的run()方法
3)在主线程中创建该类的实例对象,
4)创建Thread类对象,将3)创建的这个对象作为参数进行传递
5)分别启动线程

测试类:
package Day20_DuoJinCheng;
/**
 * @author Aoman_Hao
 */
public class RunTest {

    public static void main(String[] args) {
        //创建MyRunnable实例对象
        UseRunnalbe U1 = new UseRunnable();

        //创建Thread有参构造类对象
        Thread T1 = new Thread(U1); 
        T1.setName("T1");

        //一步走
        Thread T2 = new Thread(U1,"T2");

        //启动多线程
        T1.start();
        T2.start();


    }

}
实例对象类:
package Day20_DuoJinCheng;
/**
 * @author Aoman_Hao
 */
public class UseRunnable implements Runnable {


    @Override
    public void run() {
        for(int i=1;i<20;i++){
            //间接的使用Thread类的静态功能得到线程名称
            System.out.println(Thread.currentThread().getName()+"数字:"+i);
        }
    }

}
输出:
T1数字:1
T2数字:1
T1数字:2
T2数字:2
T1数字:3
T2数字:3
T1数字:4
T2数字:4
T1数字:5
T2数字:5
T1数字:6
T2数字:6
T1数字:7
T2数字:7
T1数字:8
T2数字:8
T1数字:9
T2数字:9
T1数字:10
T2数字:10
T1数字:11
T2数字:11
T1数字:12
T2数字:12
T1数字:13
T2数字:13
T1数字:14
T2数字:14
T1数字:15
T2数字:15
T1数字:16
T2数字:16
T1数字:17
T2数字:17
T1数字:18
T2数字:18
T1数字:19
T2数字:19

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
总结:
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类


public final void join() –throws InterruptedException等待该线程终止。
public final int getPriority()–返回线程的优先级。
public static void yield()–暂停当前正在执行的线程对象,并执行其他线程。

测试类
package Day20_DuoJinCheng;
/**
 * @author Aoman_Hao
 */
public class Demo {

    public static void main(String[] args) {
        //实现Runnable接口的类
        UseRunnable ur = new UseRunnable();

        //创建多线程的类
        Thread T1 = new Thread(ur,"T1"); 
        Thread T2 = new Thread(ur,"T2"); 
        Thread T3 = new Thread(ur,"T3"); 

        //获取优先级等级数
        int p2_pri = T2.getPriority();
        System.out.println(p2_pri);
        //设置优先级等级数
        T2.setPriority(10);
        System.out.println(T2.getPriority());

        //启动多线程
        T1.start();
        //join 等待进程终止
        try {
            T1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        T2.start();
        T3.start();


    }

}

对象类:
package Day20_DuoJinCheng;
/**
 * @author Aoman_Hao
 */
public class UseRunnable implements Runnable {


    @Override
    public void run() {
        for(int i=1;i<20;i++){
            //间接的使用Thread类的静态功能得到线程名称
            System.out.println(Thread.currentThread().getName()+"数字:"+i);
            //public static void yield()暂停当前正在执行的线程对象,并执行其他线程。
            Thread.yield();

        }
    }

}

public final void setDaemon(boolean on) –on指定true,就是设置守护线程…
将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动线程前调用。

jvm自动退出,对于主线程的数据如果直接输出完毕,对于两个守护线程来说不会立即消失,Jvm等会就自动退出.
线程停止:
public final void stop():强迫线程停止执行
public void interrupt()中断线程。 表示中断线程一种状态

  • setDeamon(boolean on):(用的多)
  • sleep():线程睡眠 (用的多)
  • wait():线程等待

sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

测试类:
package Day20_Duo;
/**
 * @author Aoman_Hao
 */
public class Demo2 {

    public static void main(String[] args) {
        CopyUseRunnable C = new CopyUseRunnable();
        Thread t1 = new Thread(C,"T1");
        Thread t2 = new Thread(C,"T2");
        Thread t3 = new Thread(C,"T3");

        //设置t1为守护线程,主程序计算完,守护线程的数据慢慢运行
        t1.setDaemon(true);

        //stop过时了,依旧可用,现在不推荐这种用法
//      t2.stop();

        //public void interrupt()中断线程。 表示中断线程一种状态
        t2.interrupt();

        t1.start();
        t2.start();
        t3.start();


    }

}
对象类:
package Day20_Duo;
/**
 * @author Aoman_Hao
 */
public class CopyUseRunnable implements Runnable {


    @Override
    public void run() {
        for(int i=1;i<20;i++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //间接的使用Thread类的静态功能得到线程名称
            System.out.println(Thread.currentThread().getName()+"数字:"+i);

        }
    }

}
输出:
T3数字:1
T1数字:1
T2数字:1
T3数字:2
T2数字:2
T1数字:2
T1数字:3
T2数字:3
T3数字:3
T1数字:4
T2数字:4
T3数字:4
T2数字:5
T1数字:5
T3数字:5
T2数字:6
T1数字:6
T3数字:6
T2数字:7
T1数字:7
T3数字:7
T1数字:8
T2数字:8
T3数字:8
T1数字:9
T2数字:9
T3数字:9
T1数字:10
T2数字:10
T3数字:10
T1数字:11
T2数字:11
T3数字:11
T2数字:12
T1数字:12
T3数字:12
T1数字:13
T2数字:13
T3数字:13
T1数字:14
T2数字:14
T3数字:14
T1数字:15
T2数字:15
T3数字:15
T1数字:16
T2数字:16
T3数字:16
T1数字:17
T2数字:17
T3数字:17
T1数字:18
T2数字:18
T3数字:18
T2数字:19
T1数字:19
T3数字:19

t2运行stop,t2线程直接结束,不在运行,抢CPU。


标签:Thread,void,线程,new,多线程,public,小记
From: https://blog.51cto.com/u_16066155/6185074

相关文章

  • 4.8 模拟赛小记
    补。每次到模拟赛就真切的感觉到什么都不会了捏!感觉看着题目读了好几遍仍没有感觉,我不能感受到我的脑子在哪里。脑子在哪里呢?T1中位数考场想的暴力和正解有一丝的相似之处,但毕竟是暴力,90pts的暴力,更重要的是暴力写挂了。嘿嘿,统计了答案忘记往ans里去加了!非常的强大。关......
  • 【ZYNQ】Vivado HLS端口约束小记
    【问】为什么m_axi要设置depth参数?【ChatGPT答】m_axi是一种用于FPGA设计中的总线协议,用于实现高速数据传输。在使用m_axi时,需要设置depth参数来定义队列的深度,以确保传输的可靠性和性能。队列是一种在数据传输过程中存储数据的结构。当发送数据的速度大于接收数据的速度时,队......
  • 「Solution Set」4.11 小记
    P3642[APIO2016]烟火表演我不太会证明凸性。像这道题就是列出DP方程,\(f_{u,x}\)表示以\(u\)为根的子树还有\(x\)分钟就全爆炸的最小代价。然后赌它是个凸函数((因为它有\(sum\),就是两个下凸函数相加,还是下凸的。然后求前缀的最小值再加一个函数一类的,所以考虑之后这......
  • pytdx多线程示例
    #encoding=utf-8importmathfrompytdx.hqimportTdxHq_APIimportpathlibimportmultiprocessingasmpfrommultiprocessingimportPoolclassmyTdx:def__init__(self):self.HqHOSTS=pathlib.Path("HqHOSTS.txt").read_text().split(......
  • 关联规则小记
    1.事务是一个明确定义的商业行为.事务数据库研究的一个最普通的例子就是寻找项的集合.或叫做项集(在一些事务中一起出现的项).包含i个项的项集被称为i-项集.包含该项机的事务的百分数叫做该项集的支持度.对于有研究价值的项集,它的支持度必须比用户指定的最小值要大.这样的项集叫......
  • 多线程事务的提交解决办法
    多线程处理的时候,如果发生了错误,不会因为加了@Transcational注解而生效,这里需要额外使用SqlSessionTemplate{//插入主表electronicTaxBillMapper.insertBatch(masterList);//更新出库单状态outOrderDetailMapper.updateByOrderCodeList(orderCodeList);//切......
  • Windows系统下DoH配置小记
    Windows系统下DoH配置小记浏览器Edge打开edge://settings/privacy使用安全的DNS指定如何查找网站的网络地址设置自定义服务商为https://doh.opendns.com/dns-query{?dns}Firefox打开设置-网络设置启用基于HTTPS的DNS选择自定义提供商为https://doh.opendns.com/dns-......
  • 2023/4/10小记
    题先咕咕咕,写小记主要是为了说废话。学whk的感觉大概就是这样。睁开眼重新堕入平凡的世界辗转枯燥的时间一天又一天曾为之绚乱的爱是那么遥远——《八重回归·真》讲真我真的感觉我早晚能把妄想症全搬一遍,就算知道很幼稚但是真的忍不住被戳心窝子。太像了。当时推游戏的......
  • c++ 多线程摘记
    有没有linux和windows通用的多线程库?ChatGPT:是的,C++11标准引入了一个名为std::thread的多线程库,它可以在Windows和Linux上使用。std::thread库提供了一种方便的方式来创建和管理线程,包括启动、等待、终止和同步线程。此外,它还提供了一些便利的功能,例如线程局部存储......
  • 介绍几种等待多线程任务执行完毕的方法
    一.引言:在我们日常的开发过程中,我们经常会开启多个线程或者创建一个线程池去执行多个并发任务,当所有任务执行完毕后,我们一般会做一个统一的处理。那我们如何知道多个线程的任务已经全部执行完毕了呢?今天由我来为大家介绍几种方法:二.join()方法在这里插入图片描述......