【Java并发编程】创建线程的几种方式你都知道吗?

创建线程的几种方法

继承Thread类创建线程

java 复制代码
public class Creation {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("running...");
    }
}

实现Runnable接口创建线程

java 复制代码
public class Creation {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        Thread thread = new Thread(myThread);
        thread.start();
    }
}

class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println("running...");
    }
}

Thrad和Runnable的关系

Thread实现了Runable接口。

java 复制代码
public class Thread implements Runnable {
    
    private Runnable target;
    
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
    
    @Override
    public void run() {
        if (target != null) {
            // 1.要么重写 Runnable 的 run 方法。
            // 2.要么传入 Runnable 的实现类,调用其 run 方法。
            target.run();
        }
    }
}

Thread与Runable创建线程区别

Runnable可理解为资源,Thread理解为处理资源的线程。

1、继承Thread类的方式,new了三个Thread,实际上是有300张票。

2、实现Runnable接口的方式,new了三个Thread,实际上是有100张票。

3、也就是说实现Runnable接口的线程中,成员属性是所有线程共有的。但是继承Thread类的线程中,成员属性是各个线程独有的,其它线程看不到,除非采用static的方式才能使各个线程都能看到。

4、就像上面说的Runnable相当于资源,Thread才是线程。用Runnable创建线程时,new了多个Thread,但是传进去的参数都是同一个Runnable(资源)。用Thread创建线程时,就直接new了多个线程,每个线程都有自己的Runnable(资源)。在Thread源码中就是用target变量(这是一个Runnable类型的变量)来表示这个资源。

5、同时因为这两个的区别,在并发编程中,继承了Thread的子类在进行线程同步时不能将成员变量当做锁,因为多个线程拿到的不是同一把锁,不过用static变量可以解决这个问题。而实现了Runnable接口的类在进行线程同步时没有这个问题。

java 复制代码
class Window extends Thread{

    private  int ticket = 100;
    @Override
    public void run() {

        while(true){

            if(ticket > 0){
                System.out.println(getName() + ":卖票,票号为:" + ticket);
                ticket--;
            }else{
                break;
            }

        }

    }
}


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


        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

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

    }
}
java 复制代码
class Window1 implements Runnable{

    private int ticket = 100;

    @Override
    public void run() {
        while(true){
            if(ticket > 0){
                System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
                ticket--;
            }else{
                break;
            }
        }
    }
}


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

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

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

}

实现Callable接口创建线程

java 复制代码
package sort.impl.juc;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * @author WanJie
 * @since 2023-08-09 11:29
 */
public class Creation {
    public static void main(String[] args) {
        FutureTask<String> futureTask = new FutureTask<String>(new MyThread());
        Thread thread = new Thread(futureTask);
        thread.start();
    }
}

class MyThread implements Callable {
    @Override
    public Object call() throws Exception {
        System.out.println("running");
        return "0K";
    }
}
相关推荐
高频因子挖掘机17 分钟前
QuantDash 明明安装成功,为什么 Python 还是无法 import?
后端·github·api
Pniubi7 小时前
HashMap的扩容和树化边界
java·开发语言
Mikko77 小时前
用 Java 复刻了高中时在塞班上玩的「熔岩矿车」:纯 Swing、零依赖、没有一张图片,一个 jar 双击就能玩
java·游戏开发·swing
知了学历孙老师7 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
Java爱好狂.8 小时前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
秋饼9 小时前
LLM API密钥动态轮换实战:Spring Vault + Spring AI + 多Provider路由
java·ai·技术分享·后端开发
马良神笔10 小时前
2026 年Rag最近技术前沿总结
后端·python·django
程序猿DD10 小时前
同样10美元,OpenDesign和Command Code的DeepSeek V4.1 Flash额度到底有多少?
后端
福兮说10 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
高频因子挖掘机10 小时前
A股量化从日线升级到5分钟线:数据量增加后最先暴露哪些工程问题?
后端·github·api