程序,进程,线程和创建方法。文字不多,代码为主,自学用,谨慎借鉴,有错误请指正

目录

程序,线程,进程的概念

创建线程的第一种方法:extends Thread 并重写run()

获取当前线程的名字:

方法一:通过Thread.currentThread()和set,get方法

方法二:通过构造器

经典的买火车票的问题:

创建线程的第二种方法:实现Runnable接口

再次重写买火车票

创建线程的第三种方法:implements Callable重写call()

线程的生命周期 

程序,线程,进程的概念

程序:是为了完成特定任务、用某种语言编写的一组指令的集合,是一段静态代码。(程序是静态的)

进程(process):是程序的一次执行过程,正在运行的一个程序,进程作为资源分配的单位,在内存中会为每个进程分配不同的内存区域。(进程是动态的)是一个懂得过程。进程的生命周期:有他自身的产生,存在和消亡的过程

线程(thread):进程可进一步细化为线程,是一个程序内部的一条执行路径。若一个进程同一时间并行执行多个线程,就支持多线程。

---------------------------------------------------------------------------------------------------------------------------------

进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。

线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程
例子:

360杀毒软件(程序)--->启动杀毒、木马查杀、清理垃圾(三个线程同时进行)--->电脑体检进程(一个进程包含了三个线程)

创建线程的第一种方法:extends Thread 并重写run()

// 方法一:extends Thread后重写run()
public class ThreadTest1 extends Thread{
    @Override
    public void run(){
        // 输出1-10
        for (int i = 0; i <= 10; i++) {
            System.out.println("thread/run:" + i);
        }
    }
}

    @Test
    public void test01(){
        ThreadTest1 tt = new ThreadTest1();
        //tt.run(); // 这个方法不能直接实用,会被当成TT1类中的普通方法
        tt.start();// start()是Thread中的,运行这个方法才是开启线程,完成和主程序抢夺资源的操作
        for (int i = 0; i <=10 ; i++) {
            System.out.println("test01:" + i);
        }
    }

结果:成功抢夺了资源

获取当前线程的名字:

        方法一:通过Thread.currentThread()和set,get方法

public class ThreadTest1 extends Thread{

    @Override
    public void run(){
        // 输出1-10
        for (int i = 0; i <= 10; i++) {
            System.out.println(this.getName() + "thread/run:" + i);
        }
    }
}
    @Test
    public void test01(){
        ThreadTest1 tt = new ThreadTest1();
        tt.setName("子线程");// 设置当前子线程的名字
        tt.start();
        // Thread.currentThread():获取当前线程
        Thread.currentThread().setName("主线程");//设置主线程的名字
        for (int i = 0; i <=10 ; i++) {
            System.out.println(
                    Thread.currentThread().getName() // 获取当前线程的名字
                    + "test01:" + i);
        }
    }

结果:成功

方法二:通过构造器

// 创建线程的方法一:extends Thread后重写run()
public class ThreadTest1 extends Thread{
    
    public ThreadTest1() {
    }
    // 获取当前线程的第二种方法:构造器
    public ThreadTest1(String name) {
        super(name);
    }

    @Override
    public void run(){
        // 输出1-10
        for (int i = 0; i <= 10; i++) {
            System.out.println(this.getName() + "thread/run:" + i);
        }
    }
}
    @Test
    public void test02(){
        ThreadTest1 tt = new ThreadTest1("子线程");
        tt.start();
        Thread.currentThread().setName("主线程");
        for (int i = 0; i <=10 ; i++) {
            System.out.println(
                    Thread.currentThread().getName() + "test01:" + i);
        }
    }

经典的买火车票的问题:

public class TicketThread01 extends Thread{
    static int ticketNumber = 10;

    public TicketThread01() { }

    public TicketThread01(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if(ticketNumber > 0){
                System.out.println("我在" + this.getName() + "买到了第" + ticketNumber-- +"张票");
            }
        }
    }
}
public static void main(String[] args) {
        TicketThread01 tt1 = new TicketThread01("窗口1");
        tt1.start();
        TicketThread01 tt2 = new TicketThread01("窗口2");
        tt2.start();
        TicketThread01 tt3 = new TicketThread01("窗口3");
        tt3.start();
    }

成功(junit测试,该段代码无法运行)

创建线程的第二种方法:实现Runnable接口

public class ThreadTest2 implements Runnable{
    @Override
    public void run() {
        // 输出1-10
        for (int i = 0; i <= 10; i++) {
            System.out.println(Thread.currentThread().getName() + "ThreadTest2的run" + i);
        }
    }
}
    @Test
    public void test01(){
        ThreadTest2 tt = new ThreadTest2();
        Thread t = new Thread(tt,"子线程");
        t.start();

        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + "主线程的" + i);
        }
    }

测试结果:成功

再次重写买火车票

public class TicketThread02 implements Runnable{
    // 因为这次测试类中三个线程共用tt对象,所以tn不用static修饰
    int ticketNumber = 10;
    @Override
    public void run() {
        for (int i = 1; i <= 100 ; i++) {
            if(ticketNumber > 0){
                System.out.println("我在" + Thread.currentThread().getName() + "窗口买到第" + ticketNumber-- + "张票");
            }
        }
    }
}
    public static void main(String[] args) {
        TicketThread02 tt = new TicketThread02();
        Thread t1 = new Thread(tt,"窗口1");
        t1.start();
        Thread t2 = new Thread(tt,"窗口2");
        t2.start();
        Thread t3 = new Thread(tt,"窗口3");
        t3.start();
    }

成功,但有时候会出现两次一样的第i张车票,或者是-1,-2这种情况:

线程不安全--->在《线程安全问题》那里解决

创建线程的第三种方法:implements Callable<v>重写call()

该方法特点:1.有返回值,2.抛异常

public class ThreadTest3 implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        return new Random().nextInt(10);
    }
}
    @Test
    public void test01() throws ExecutionException, InterruptedException {
        ThreadTest3 tt = new ThreadTest3();
        FutureTask<Integer> ft = new FutureTask<>(tt);
        Thread t = new Thread(ft);
        t.start();
        Integer integer = ft.get();
        System.out.println(integer);
    }

成功

线程的生命周期 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值