java-线程


一、线程的概念

程序是对数据描述与操作的一段静态代码的有序集合,是应用程序执行的脚本。进程是程序的一次执行过程,它对应从代码加载、执行到执行完毕的一个完整过程。系统运行一个程序就是个进程从创建、运行到消亡的过程。进程是程序在一个数据集合上运行的过程,是系统进行资源分配和调度的一个独立单位。

线程是比进程更小的运行单位,是能独立运行的基本单位,也是能独立调度和分派的基本单位。一个进程在执行的过程中,可以产生多 个线程,并且这些线程之间可以并发执行,甚至允许在一个进程中所有 的线程都能并发执行。 就好比生活中,我们在听音乐的同时还可以看书一样。

在Java中,线程由三部分组成:虚拟的CPU、代码和数据。

(1)虚拟的CPU:专门用于执行线程的任务。在Java中,由java. lang. Thread类封装和虚拟。

(2)代码:线程中执行的指令,即程序中特定的方法。在Java中,构造Thread类时,传递给Thread类对象。

(3)数据:线程中要处理的数据,即程序中的变量等。

并发: 指两个或多个事件在同一个时间段内发生。
并行: 指两个或多个事件在同一时刻发生(同是发生)。

二、Thread类和Runnable接口

Java中,创建线程的方法有两种:一是通过继承线程类Thread来创建线程;二是建立一个实现Runnable接口的类。
演示如下:

package com.hg.day22.demo01;

public class Person extends Demo01MAainThread{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person(){
    }
    public Person(String name){
        this.name = name;
    }

    public void run(){
        for (int i = 0; i <20;i++)
        {
            System.out.println(name+"--->"+i);
        }
    }
}

package com.hg.day22.demo01;

/*
主线程   执行main()方法的线程
单线程程序:只有一个程序
 */
public class Demo01MAainThread {
    public static void main(String[] args) {
        Person p1=new Person("小强");
        p1.run();

//        System.out.println(0/0);

        Person p2=new Person("小刚");
        p2.run();
    }
}

运行结果如下:
在这里插入图片描述

package com.hg.day22.demo01;
//1、创建子类
public class MyThread extends Thread {
//2、才重写run方法
    //重写
    @Override
    public void run() {
        for (int i = 0; i <20;i++)
        {
            System.out.println("子线程"+i);
        }
    }

}

package com.hg.day22.demo01;

import com.hg.day22.demo02.MyThread;

/*
java.long.Thread

实现步骤:
    创建一个thread类的子类
    在thread子类中重写run方法,设置线程任务(干什么)
    创建thread子类的对象
    调用thread类中的方法start来的启动线程,执行main方法

 */
public class Demo01Thread {
    public static void main(String[] args) {
        //3、创建子类的对象
        com.hg.day22.demo02.MyThread mt=new com.hg.day22.demo02.MyThread();
        //4、调用这个方法
        mt.start();//子线程0

        for (int i = 0; i <20;i++)
        {
            System.out.println("主线程"+i);
//            if(i==10)
//                System.out.println(0/0);
        }
    }
}

运行结果如下:
在这里插入图片描述

三、主线程与线程的生命周期

线程是一个动态的执行过程:就如人的生老病死,一个线程的生命周期要经历创建、就绪、运行、挂起、终止5中状态。
创建–>就绪–>运行–>挂起–>终止
演示如下2:

package com.hg.day22.demo02;
//1、创建子类
public class MyThread extends Thread {
//2、才重写run方法
    //重写
    @Override
    public void run() {

//        String name =getName();
//        System.out.println("run"+name);

        System.out.println("子"+Thread.currentThread().getName());
    }

}

package com.hg.day22.demo02;

/*
java.long.Thread

实现步骤:
    创建一个thread类的子类
    在thread子类中重写run方法,设置线程任务(干什么)
    创建thread子类的对象
    调用thread类中的方法start来的启动线程,执行main方法

 */
public class Demo01Thread {
    public static void main(String[] args) {
        //3、创建子类的对象
        MyThread mt=new MyThread();
        //4、调用这个方法
        mt.start();//子线程0

        new MyThread().start();//子线程1
        new MyThread().start();//子线程2
        new MyThread().start();//子线程3

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


    }
}

运行结果如下:
在这里插入图片描述

package com.hg.day22.demo02;

public class MyThreadName extends Thread{
    public MyThreadName() {}

    public MyThreadName(String name) {
        super(name);//把线程的名称传递给父类,让父类thread给子线程起一个名字
    }

    @Override
    public void run() {
//        String name =getName();
//        System.out.println("run"+name);

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

}


package com.hg.day22.demo02;

public class Demo02ThreadSetName {
    public static void main(String[] args) {
        MyThreadName mt=new MyThreadName("小强");
        mt.start();
        new MyThreadName("旺财").start();
    }
}

运行结果如下:
在这里插入图片描述

四、线程状态控制方法—线程休眠

如果希望线程休眠一段时间可以使用sleep(long)的方法。
演示如下:

package com.hg.day22.demo03;

public class Demo03Sleep {
    public static void main(String[] args) {
        for (int i = 1; i <60;i++)
        {
            System.out.println(i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果如下:

五、实现runnable接口创建多线程的好处

1、避免了单继承的局限性
2、增强了程序的扩展性,降低了程序的耦合性

演示如下:

package com.hg.day22.demo04;

public class RunableImpl2  implements Runnable {
//    @Override
    public void run() {
        for(int i=0;i<20;i++)
        {
            System.out.println("hello");
        }
    }
}

package com.hg.day22.demo04;
//1、创建一个runnable接口实现类
public class RunnableImpl implements Runnable {
//2、在实现类中 重写Override
    @Override
    public void run() {
        for(int i = 0; i <20;i++)
        {
            System.out.println(Thread.currentThread().getName() +"---->"+i);

        }
    }
}

package com.hg.day22.demo04;

public class Demo04Runnable {
    //3、创建一个runnable接口是实现类 对象
    public static void main(String[] args) {
        RunnableImpl run =new RunnableImpl();
        //4、创建Thread类对象,构造方法中传递Runnable接口实现类对象
//        Thread t=new Thread(run);
        //5、调用Thread 累计中的start方法,启动子线程

        Thread t=new Thread(new RunableImpl2());
        t.start();
        for(int i = 0; i <20;i++)
        {
            System.out.println(Thread.currentThread().getName() +"---->"+i);

        }
    }
}

运行结果如下:
在这里插入图片描述

六、实例:使用 synchronized出售电影票

package com.hg.day22.demo05;

/*
解决线程安全的一种方案:使用同步代码块
格式:
    synchronized(锁对象){
        可能会出现线程安全的代码(是因为访问了共享的数据)
    }
    注意:
        1、通过代码块中的锁对象,可以使用任意的对象
        2、但是必须保证多个线程使用的锁对象是同一个
        3、锁对象作用:
            把同步代码块锁住,只让一个线程执行
 */
public class RunnableImpl implements Runnable{
    private int ticket = 100;
    Object obj=new Object();
    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "--->正在卖第" + ticket + "张票");
                    ticket--;
                }
            }

        }
    }
}

package com.hg.day22.demo05;

public class Demo01Ticket {
    public static void main(String[] args) {
        RunnableImpl run=new RunnableImpl();
        Thread t0=new Thread(run);
        Thread t1=new Thread(run);
        Thread t2=new Thread(run);

        t0.start();
        t1.start();
        t2.start();
    }
}

运行结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值