黑马程序员——多线程(一)

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
1、进程: 是一个正在执行中的程序。

每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元(线程)。

2、线程:就是进程中的一个独立的控制单元。

线程控制着进程的执行。

一个进程中,至少一个或以上的线程。

3、Java JVM 启动的时候会有一个进程 Java.exe
(1)、该进程中至少有一个(当然就是多个)线程负责 Java 程序的执行。
(2)、而且这个线程运行的代码存在于 main 方法中。
(3)、该线程称为主线程。

4、扩展:其实更细节说明 Jvm ,Jvm 启动不止一个线程,还有负责垃圾回收机制的线程
5,线程状态
(1)、新状态:线程对象已经创建,还没有在其上调用start()方法。

(2)、可运行状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时,线程首先进入可运行状态。在线程运行之后或者从阻塞、等待或睡眠状态回来后,也返回到可运行状态。

(3)、运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。

(4)、等待/阻塞/睡眠状态:这是线程有资格运行时它所处的状态。实际上这个三状态组合为一种,其共同点是:线程仍旧是活的,但是当前没有条件运行。换句话说,它是可运行的,但是如果某件事件出现,他可能返回到可运行状态。

(5)、死亡态:当线程的run()方法完成时或调用stop()就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
6 创建方式
创建线程的第一种方式:继承Thread类。
如下:


package com.itheima;

public class duoxiangcheng extends Thread {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
       duoxiangcheng duo =new duoxiangcheng();
       duo.start();
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 100; i++) {
            System.err.println("A__________"+i);
        }
    }

创建线程的第二种方式:实现Runnable接口。
如下:

package com.itheima;

public class duoxiangcheng  implements Runnable{
//实现步骤: 
//
//1,定义类实现Runnable接口
//2,覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。
//3,通过Thread类建立线程对象。
//4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
//
//5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。 

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 50; i++) {
            System.err.println(Thread.currentThread().getName()+"_____"+i);

        }

    }
    public static void main(String[] args) {
        duoxiangcheng d = new duoxiangcheng();      
        Thread t1 =new Thread(d);//实例化线程
        t1.setName("d1");//设置线程名字
        t1.start();//开启线程
        Thread t2 =new Thread(d);
        t2.setName("d22");
        t2.start();
    }
}

实现方式和继承方式有什么区别:

(1)、实现方式好处:避免了单继承的局限性
(2)、在定义线程时:建议使用实现方式
(3)、两种方式区别:

   1.继承Thread:线程代码存放在 Thread 子类 run 方法中 
   2.实现Runnable:线程代码存放在接口的子类的 run 方法中

议使用第二种线程创建方法。因为第二种方式更加体现面向对象思想
附:也可以直接创建对象调用run方法,但就不是多线程运行了,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑马程序员多线程练习题主要包括两个问题。第一个问题是如何控制四个线程在打印log之前能够同时开始等待1秒钟。一种解决思路是在线程的run方法中调用parseLog方法,并使用Thread.sleep方法让线程等待1秒钟。另一种解决思路是使用线程池,将线程数量固定为4个,并将每个调用parseLog方法的语句封装为一个Runnable对象,然后提交到线程池中。这样可以实现一秒钟打印4行日志,4秒钟打印16条日志的需求。 第二个问题是如何修改代码,使得几个线程调用TestDo.doSome(key, value)方法时,如果传递进去的key相等(equals比较为true),则这几个线程应互斥排队输出结果。一种解决方法是使用synchronized关键字来实现线程的互斥排队输出。通过给TestDo.doSome方法添加synchronized关键字,可以确保同一时间只有一个线程能够执行该方法,从而实现线程的互斥输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [黑马程序员——多线程10:多线程相关练习](https://blog.csdn.net/axr1985lazy/article/details/48186039)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值