Java多线程创建的前两种方式——继承Thread类的方式和实现Runnable接口的方式

基本概念

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

进程(process):程序的一次执行过程,或是正在运行的一个程序。
进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域。

线程(thread):进程可进一步细化为线程,是一个程序内部的一条执行路径。
线程作为调度和执行的单位,每个线程拥独立的运行栈和程序计数器(pc),线程切换的开销小。

并行:多个CPU同时执行多个任务。
并发:一个CPU(采用时间片)同时执行多个任务。

1、继承Thread类的方式

步骤:

1. 创建一个继承于Thread类的子类
2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中
3. 创建Thread类的子类的对象
4. 通过此对象调用start():①启动当前线程 ② 调用当前线程的run()

(以火车站买票为例)

同步代码块
synchronized(同步监视器){
需要同步的代码
}

说明
1、操作共享数据的代码,即为需要被同步的代码。
2、共享数据:多个线程共同操作的变量。比如此例子中的stack就是共享数据。
3、同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。
要求:多个线程共同用一个同步监视器,即同用一把锁。

public class WindowTest1 {
    public static void main(String[] args) {
        Window1 w1 = new Window1();
        Window1 w2 = new Window1();
        Window1 w3 = new Window1();

        w1.setName("线程一");
        w2.setName("线程二");
        w3.setName("线程三");

        w1.start();
        w2.start();
        w3.start();
    }
}

class Window1 extends Thread{
    private static int tick = 100;

    @Override
    public void run() {
        while (true){
            synchronized (this){//解决线程安全问题
                if(tick > 0){
                    System.out.println(Thread.currentThread().getName()+"有余票,票号:"+tick--);
                }else
                    break;
            }
        }
    }
}

同步方法

public class WindowTest3 {
    public static void main(String[] args) {
        Window3 w1 = new Window3();
        Window3 w2 = new Window3();
        Window3 w3 = new Window3();

        w1.setName("线程一");
        w2.setName("线程二");
        w3.setName("线程三");

        w1.start();
        w2.start();
        w3.start();
    }
}

class Window3 extends Thread{
    private static int ticked = 100;

    @Override
    public void run() {
        while(true){
            synchronized (this) {
                show();
                if (ticked <= 0)
                    break;
            }
        }
    }

    private static synchronized void show(){
        if (ticked > 0){
            System.out.println(Thread.currentThread().getName()+"有余票,票号:"+ticked--);
        }
    }
}

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

实现Runnable接口的方式

步骤
1. 创建一个实现了Runnable接口的类
2. 实现类去实现Runnable中的抽象方法:run()
3. 创建实现类的对象
4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
5. 通过Thread类的对象调用start()

public class WindowTest {
    public static void main(String[] args) {
        Window w = new Window();
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口一:");
        t2.setName("窗口二:");
        t3.setName("窗口三:");

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

class Window implements Runnable{

    public int stack = 100;//因为接口只有一个所以不需要用静态
    
    @Override
    public void run() {
        while(true){
            synchronized (this){
                if(stack > 0){
                    System.out.println(Thread.currentThread().getName()+"有余票,票号:"+stack--);
                }else {
                    break;
                }
            }
        }
    }
}

执行结果同上

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值