Java:创建线程

介绍

1.进程是操作系统资源分配的基本单位 而线程是CPU的基本调度单位
2.一个系统运行后至少有一个进程
3.一个进程可以包含多个线程 但是至少需要有一个线程 否则这个进程是没有意义的
4.进程间不能共享数据段地址 但同进程的线程之间可以
线程基本组成部分:
	1.CPU时间片:操作系统(OS)会为每个线程分配执行时间
	2.运行数据:
		堆空间:存储线程需使用的对象 多个线程可以共享堆中的对象
		栈空间:存储线程需使用的局部变量 每个线程都拥有独立的栈

线程的特点:
	1.线程抢占执行:
		效率高
		可防止单一线程长时间独占CPU
	2.在单核CPU中,宏观上同时执行,微观上顺序执行

创建线程的两个方法

第一个方法:继承Thread类

/**
 * 创建线程的第一种方法
 * 步骤:
 *  1.继承Thread类
 *  2.重写run方法
 *  3.创建子类对象
 *  4.调用start方法
 */
public class MyThreadOne{
    public static void main(String[] args) {
        //3.创建子类对象
        MyThread1 t1 = new MyThread1();

        //4.调用start方法
        t1.start();

        //主线程
        for (int i = 0; i < 50; i++) {
            System.out.println("ID名" + Thread.currentThread().getId() + "线程名" + Thread.currentThread().getName() + ":" + i);
        }
    }
}

//1.继承Thread类
class MyThread1 extends Thread{
    //2.重写run方法
    @Override
    public void run(){
        for (int i = 0; i < 50; i++) {
            System.out.println("子线程:" + i);
        }
    }
}

获取和修改线程名字

/**
 * 获取线程名的两种方法:
 *  1.必须继承Thread类 this.getId() 和 this.getName
 *  2.无需继承Thread类 Thread.currentThread().getId() 和 Thread.currentThread().getName()
 *
 * 修改线程名的两种方法:
 *  1.直接用setName方法
 *  2.通过构造方法修改
 */
/*********************继承类*********************/
public class MyThread2 extends Thread{
    public MyThread2(){

    }
    /*************************构造方法修改线程名***************************/
    public MyThread2(String name){
        super(name);
    }


    @Override
    public void run(){
        for (int i = 0; i < 50; i++) {
            /*****************************获取线程名字*********************************/
            //必须继承Thread类 this.getId() 和 this.getName
            System.out.println("ID名" + this.getId() + "线程名" + this.getName() + ":" + i);

        }
    }
}

/************************实现类**************************/
//子线程1
MyThread2 t1 = new MyThread2();
/********************************直接用setName方法修改线程名字***************************/
t1.setName("子线程1");
t1.start();
//子线程2
MyThread2 t2 = new MyThread2();
t1.setName("子线程2");
t2.start();
//子线程3
//构造方法修改名字
MyThread2 t3 = new MyThread2("子线程3");
t3.start();
//主线程
for (int i = 0; i < 50; i++) {
    //无需继承Thread类 Thread.currentThread().getId() 和 Thread.currentThread().getName()
    System.out.println("ID名" + Thread.currentThread().getId() + "线程名" + Thread.currentThread().getName() + ":" + i);
}

继承Thread类例题:四个窗口各卖100张票

/************************票类**********************/
public class Ticket1 extends Thread{
    private int ticket = 100;

    public Ticket1(){

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

    @Override
    public void run(){
        while (ticket > 0){
            System.out.println(this.getName() + " 卖了第" + ticket  + "张票");
            ticket--;
        }
    }
}

/**************************实现类**************************/
public static void main(String[] args) {
        //创建线程对象
        Ticket1 t1 = new Ticket1("窗口1");
        Ticket1 t2 = new Ticket1("窗口2");
        Ticket1 t3 = new Ticket1("窗口3");
        Ticket1 t4 = new Ticket1("窗口4");

        //启动线程
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }

第二个方法:实现Runnable接口

/**
 * 创建线程的第二种方法:实现Runnable接口
 * 步骤:
 *  1.实现Runnable接口
 *  2.重写run方法
 *  3.创建实现类对象
 */
/*******************实现接口*********************/
public class RunnableUse implements Runnable{
    @Override
    public void run(){
        for (int i = 0; i < 50; i++) {
            System.out.println("MyRunnable" + i);
        }
    }
}

/********************实现类*********************/
//创建MyRunnable对象,表示线程要执行的功能
RunnableUse run1 = new RunnableUse();
//创建线程对象
Thread thread = new Thread(run1,"子线程1");
thread.start();
for (int i = 0; i < 50; i++) {
    System.out.println("main------" + i);
}

匿名内部类实现Runnable

public static void main(String[] args) {
        //创建匿名内部类
        //创建可运行对象
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    System.out.println(Thread.currentThread().getName() + ":" + i);
                }
            }
        };

        //创建线程对象
        Thread thread = new Thread(runnable,"子线程1");
        thread.start();
        for (int i = 0; i < 50; i++) {
            System.out.println("main-----" + i);
        }
    }

Runnable例题1:四个窗口总共卖一百张票

/**********************票类(共享资源)**************************/
//多个线程共用ticket变量
//如果是四个窗口每个都卖一百张票 则在run方法中int ticket = 100;
//仅适用于Runnable接口创建线程
public class Ticket2 implements Runnable{
    private int ticket = 100;

    @Override
    public void run() {
        while(ticket > 0){
            System.out.println(Thread.currentThread().getName() + " 卖了第" + ticket + "张票");
            ticket--;
        }
    }
}


/**********************实现类*************************/
public static void main(String[] args) {
        
        //创建票对象
        Ticket2 ticket = new Ticket();
        
        //创建线程对象
        Thread w1 = new Thread(ticket,"窗口1");
        Thread w2 = new Thread(ticket,"窗口2");
        Thread w3 = new Thread(ticket,"窗口3");
        Thread w4 = new Thread(ticket,"窗口4");
        
        //启动进程
        w1.start();
        w2.start();
        w3.start();
        w4.start();
    }

Runnable例题2:银行卡存取

/*************************银行卡类***********************/
public class BankCard {
    private double money;//余额

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

/******************实现Runnable接口存钱******************/
public class AddMoney implements Runnable{
    //实例化一个银行卡
    private BankCard card;

    public AddMoney(BankCard card) {
        this.card = card;
    }

    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            card.setMoney(card.getMoney() + 1000);
            System.out.println(Thread.currentThread().getName() + "存了1000元 余额是" + card.getMoney());
        }
    }
}

/******************实现Runnable接口取钱******************/
public class PopMoney implements Runnable{
    private BankCard card;

    public PopMoney(BankCard card) {
        this.card = card;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            if (card.getMoney() >= 1000){
                card.setMoney(card.getMoney() - 1000);
                System.out.println(Thread.currentThread().getName() + "取了1000元 余额是" + card.getMoney());
            }
            else{
                System.out.println("银行卡余额不足");
                i--;
            }
        }
    }
}

/**********************实现类*************************/
public static void main(String[] args) {
        //创建银行卡
        BankCard card = new BankCard();
        //存取钱
        AddMoney add = new AddMoney(card);
        PopMoney pop = new PopMoney(card);
        //创建线程
        Thread a1 = new Thread(add,"mans");
        Thread p1 = new Thread(pop,"womans");
        //开启线程
        a1.start();
        p1.start();
}

Runnable例题2:银行卡存取匿名内部类实现

/*************************银行卡类***********************/
public class BankCard {
    private double money;//余额

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

/**********************实现类*************************/
public static void main(String[] args) {
        BankCard card = new BankCard();

        //实现存钱Runnable接口
        Runnable addmoney = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    card.setMoney(card.getMoney() + 1000);
                    System.out.println(Thread.currentThread().getName() + "存了1000元 余额是" + card.getMoney());
                }
            }
        };

        //实现取钱Runnable接口
        Runnable popmoney = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    if (card.getMoney() >= 1000){
                        card.setMoney(card.getMoney() - 1000);
                        System.out.println(Thread.currentThread().getName() + "取了1000元 余额是" + card.getMoney());
                    }
                    else{
                        System.out.println("银行卡余额不足");
                        i--;
                    }
                }
            }
        };

        //创建并开启线程
        new Thread(addmoney,"man").start();
        new Thread(popmoney,"woman").start();
}

第三个方法:实现Callable接口

匿名内部类实现

/**
 * 创建线程的第三种方法:实现Callable接口
 * Callable具有泛型返回值 可以声明异常
 * Callable和Runnable的区别
 *     (1)Callable接口中call方法有返回值 Runnable接口中run方法没有
 *     (2)Callable接口中call方法有声明异常 Runnable接口中run方法没有异常
 *
 * 步骤:
 *     1.创建Callable对象
 *     2.将Callable对象转换为可执行对象
 *     3.创建启动线程
 *     4.获取结果
 */

public static void main(String[] args) throws Exception{
    //功能需求: 使用Callable实现累加
    //1.创建Callable对象
    Callable<Integer> callable = new Callable<Integer>() {
        private int num = 0;

        @Override
        public Integer call() throws Exception {
            for (int i = 0; i < 20; i++) {
                synchronized (this){
                    num += 1;
                    Thread.sleep(100);
                }
            }
            return num;
        }
    };

    //2.将Callable对象转成可执行任务
    //Callable对象不能直接执行 要先转为可执行任务
    FutureTask<Integer> task = new FutureTask<>(callable);

    //3.创建线程
    Thread t1 = new Thread(task);
    Thread t2 = new Thread(task);

    //4.启动线程
    t1.start();
    t2.start();

    //5.获取结果(等call执行完毕才会返回)
    Integer sum = task.get();
    System.out.println(sum);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值