精华内容
下载资源
问答
  • 创建线程的方式
    千次阅读
    2022-03-22 15:26:58

    创建线程的几种方式: 


    方式1:通过继承Thread类创建线程
    步骤:1.定义Thread类的子类,并重写该类的run方法,该方法的方法体就是线程需要执行的任务,因此run()方法也被称为线程执行体
    2.创建Thread子类的实例,也就是创建了线程对象
    3.启动线程,即调用线程的start()方法

    方式2:通过实现Runnable接口创建线程
    步骤:1.定义Runnable接口的实现类,一样要重写run()方法,和第一种方式一样,这里的run()方法也是线程的执行体
    2.创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread类才是真正的线程对象
    3.依然是通过调用线程对象的start方法来启动线程

    方式3:使用Callable和Future来创建线程
    注意:和Runnable接口不一样,Callable接口提供了一个call()方法来作为线程的执行体,call()方法比run()方法功能要更加强大,call()方法可以有返回值,call()方法可以声明抛出异常(前两种如果要抛异常只能通过try,catch来实现)。
    步骤:1.创建Callable接口的实现类,并实现call()方法,然后创建该类的实例
    2.使用Future Task类来包装Callable对象。该FutureTask对象封装了Callable对象的call()方法的返回值
    3.使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口并在重写的run方法中执行call方法)
    4.调用FutureTask对象的get方法来获取线程执行结束后的返回值

    方法4:通过线程池来创建线程
    注意:ExecutorService es = Executors.newFixedThreadPool(30);
    ExecutorService es = Executors.newCachedThreadPool();
    FixedThreadPool创建的线程池-》用户可以指定线程池大小,但指定了就不可变
    CachedThreadPool创建的线程池-》线程池大小可变

    几种创建线程方式的对比:
    实现Runnable和实现Callable接口方式基本相同,不过是后者执行call方法并且有返回值,而run方法无任何返回值,因此可以把这两种方式归为一种方式与继承Thread类的方式进行对比,差别如下(以实现接口方式为主):
    1.线程只是实现Runnable接口或Callable接口,还可以继承其他类(有点像接口和抽象类的区别,java是单继承的,但可以实现多个接口)
    2.实现接口的方式多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形
    3.如果需要访问当前线程,必须调用Thread.currentThread方法
    4.继承Thread类的线程类不能再继承其他父类(java单继承决定)
    因此,一般推荐采用实现接口的方式来创建线程。

    更多相关内容
  • C++创建线程方式

    千次阅读 2020-09-14 14:13:30
    C++ 创建线程方式如下: 1,CreateThread; 2,_beginthreadex; 3,C++11 标准下的std::thread; 4,MFC 下的AfxBeginThread; 5,Qt 下的QThread 创建线程方式1:CreateThread static HANDLE CreateThread( ...

    C++ 创建线程方式如下:

    • 1,CreateThread;
    • 2,_beginthreadex;
    • 3,C++11 标准下的std::thread;
    • 4,MFC 下的AfxBeginThread;
    • 5,Qt 下的QThread
      创建线程方式1:CreateThread
    static HANDLE CreateThread(
       LPSECURITY_ATTRIBUTES lpsa,
       DWORD dwStackSize,
       LPTHREAD_START_ROUTINE pfnThreadProc,
       void* pvParam,
       DWORD dwCreationFlags,
       DWORD* pdwThreadId 
    ) throw( );
    

    CreateThread 线程相关函数:

    CreateThread() 创建一个线程
    
    ExitThread() 正常结束一个线程的执行
    
    TerminateThead() 强制终止一个线程的执行
    
    ResumeThread() 重启一个线程
    
    SuspendThread() 挂起一个线程
    
    GetExiCodeThread() 得到一个线程的退出码
    
    GetThreadPriority() 得到一个线程的优先级
    
    SetThreadPriority() 设置一个线程的优先级
    
    CloseHandle() 关闭一个线程的句柄
    
    CreateRemoteThread() 再另一个进程中创建一个新线程
    
    PostThreadMessage() 发送一条消息给指定的线程
    
    GetCurrentThread() 得到当前的线程句柄
    
    GetCurrentThreadId() 得到当前线程的ID
    
    GetThreadId() 得到指定线程的ID
    
    WaitForSingleObject() 等待单个对象
    
    WaitForMultipleObjects() 等待多个对象
    
    static DWORD WINAPI myThreadFun(LPVOID lp);
    /***************1 CreateThread *******************/
    	HANDLE m_myCreateThread = CreateThread(NULL,//线程安全属性
    		0,//堆栈大小
    		CCWTestThreadDlg::myThreadFun,//线程函数
    		0,//线程参数
    		0,//线程创建属性
    		NULL);//线程ID
    
    	if (m_myCreateThread == INVALID_HANDLE_VALUE)
    	{
    		AfxMessageBox(L"INVALID_HANDLE_VALUE ");
    		return;
    	}
    	//设置线程优先级
    	SetThreadPriority(m_myCreateThread, THREAD_PRIORITY_ABOVE_NORMAL);
    	ResumeThread(m_myCreateThread);
    	//关闭线程
    	CloseHandle(m_myCreateThread);
    
    DWORD WINAPI CCWTestThreadDlg::myThreadFun(LPVOID lp)
    {
    	while (true)
    	{
    	}
    
    	return 0;
    }
    

    创建线程方式2:_beginthreadex

    static unsigned __stdcall myBeginThreadFun(void* pArguments);
    /***************2 _beginthreadex *******************/
    	HANDLE  m_myBeginThread = (HANDLE)_beginthreadex(NULL, 0, CCWTestThreadDlg::myBeginThreadFun, NULL, 0, NULL);
    	if (m_myBeginThread == INVALID_HANDLE_VALUE)
    	{
    		AfxMessageBox(L"m_myBeginThread INVALID_HANDLE_VALUE");
    		return;
    	}
    	//设置线程优先级
    	SetThreadPriority(m_myBeginThread, THREAD_PRIORITY_ABOVE_NORMAL);
    	ResumeThread(m_myBeginThread);
    	//关闭线程
    	CloseHandle(m_myBeginThread);
    
    unsigned __stdcall CCWTestThreadDlg::myBeginThreadFun(void* pArguments)
    {
    	while (true)
    	{		
    	}
    	return 0;
    }
    

    创建线程方式3:C++11 标准下的std::thread

    /***************4 std::thread *******************/
    void myC11ThreadFun();
    	std::thread m_pthreadc11;
    	m_pthreadc11 = std::thread(&CCWTestThreadDlg::myC11ThreadFun, this);
    	//m_pthreadc11.join();
    
    	//关闭线程
    	if (m_pthreadc11.joinable())
    	{
    		m_pthreadc11.detach();
    	}
    void CCWTestThreadDlg::myC11ThreadFun()
    {
    	while (true)
    	{
    		if (/*m_bStop*/)
    		{
    			break;
    		}
    	}
    }
    

    创建线程方式4:MFC 下的AfxBeginThread

    static UINT myAfxThreadFun(LPVOID pParam);
    /***************3 AfxBeginThread *******************/
    	/*AfxBeginThread 的第一个窗体创建辅助线程。 第二个窗体创建了一个可用作用户界面线程或辅助线程的线程。
    	AfxBeginThread 可创建新的 CWinThread 对象,调用其 CreateThread 函数以开始执行线程,然后将指针返回到线程。 
    	在整个过程中进行检查,确保假如创建过程的任何部分出现故障,所有对象都能被正确地解除分配。 
    	若想关闭线程,请从线程内调用 AfxEndThread,或从辅助线程的控制函数返回。
    	应用程序必须启用多线程;否则此函数将失败。 有关启用多线程的更多信息,请参考 Visual C++ 编译器选项下的 /MD、/MT、/LD(使用运行库)。
    	*/
    	m_pmyAfxThread = AfxBeginThread(CCWTestThreadDlg::myAfxThreadFun, this, THREAD_PRIORITY_ABOVE_NORMAL, 0, 0);
    	if (m_pmyAfxThread == nullptr)
    	{
    		AfxMessageBox(L"m_pmyAfxThread INVALID_HANDLE_VALUE");
    		return;
    	}
    UINT CCWTestThreadDlg::myAfxThreadFun(LPVOID pParam)
    {
    	while (true)
    	{
    		if (m_bStop)
    		{
    			//内部释放线程
    			AfxEndThread(m_pmyAfxThread->m_nThreadID);
    		}
    	}
    }
    

    创建线程方式5:Qt 下的QThread

    #ifndef MYQTHREAD_H
    #define MYQTHREAD_H
    
    #include <QThread>
    
    class myQThread : public QThread
    {
    	Q_OBJECT
    
    public:
    	myQThread(QObject *parent);
    	~myQThread();
    public:
    	void run();
    private:
    	
    };
    
    #endif // MYQTHREAD_H
    
    #include "myqthread.h"
    
    #include <QDebug>
    myQThread::myQThread(QObject *parent)
    	: QThread(parent)
    {
    
    }
    
    myQThread::~myQThread()
    {
    
    }
    
    void myQThread::run()
    {
    	while (1)
    	{
    		qDebug() << "test";
    	}
    }
    
    
    	myQThread *m_pmythread;
    	m_pmythread = new myQThread(this);
    	m_pmythread->start();
    	m_pmythread->setPriority(QThread::HighPriority);
    

    分析:
    方式1和2线程内部不停止也可释放,其他方式线程内部需要停止才可释放,相比其他方式的线程,方式1和2也相对安全。

    展开全文
  • java创建线程的四种方式

    千次阅读 2022-03-14 11:52:41
    4.使用线程池创建线程 1.直接初始化Thead类,实现Runnable接口 查看Thread类源码可以发现,有下面这么一个构造参数,target是线程启动的时候要调用的方法(Runnable接口中有个run方法),如果为空,那这个类的运行...

    目录

    1.直接初始化Thead类,实现Runnable接口

    2.继承Thread类

    3.实现callable接口

    4.使用线程池创建线程


    1.直接初始化Thead类,实现Runnable接口

    查看Thread类源码可以发现,有下面这么一个构造参数,target是线程启动的时候要调用的方法(Runnable接口中有个run方法),如果为空,那这个类的运行方法什么都不做

    那我们是否可以直接初始化线程,然后调用start方法启动呢

    答案是可以的

        public Thread(Runnable target) {
            init(null, target, "Thread-" + nextThreadNum(), 0);
        }

    测试代码如下

        public static void main(String args[]){
            new Thread(new Runnable(){
    
                @Override
                public void run() {
                    System.out.println("test create thread by Runable");
                }
            }).start();
        }
        
    Connected to the target VM, address: '127.0.0.1:57009', transport: 'socket'
    test create thread by Runable
    Disconnected from the target VM, address: '127.0.0.1:57009', transport: 'socket'

    当然我们也可以写一个类去实现Runnable接口

    测试代码如下

    class Demo implements Runnable{
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }
    
    public static void main(String args[]) {
        Demo d = new Demo();
        Thread thread1 = new Thread(d,"first thread");
        Thread thread2 = new Thread(d,"second thread");
        thread1.start();
        thread2.start();
    }
        
    Connected to the target VM, address: '127.0.0.1:65445', transport: 'socket'
    second thread
    first thread
    Disconnected from the target VM, address: '127.0.0.1:65445', transport: 'socket'

    上面这种方式只new了一个Demo,所以thread1和thread2会共享类中的局部变量

    我们测试下这种方式共享局部变量的效果,可以仔细看看count这个变量的变化,每个线程不是10->1这么变化的,说明count这个变量被2个线程共享了

    class Demo implements Runnable{
    
        private int count =10;
        @Override
        public void run() {
            for(int i=0;i<10;i++){
                System.out.println(Thread.currentThread().getName()+count--);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
        }
    }
    
    public static void main(String args[]) {
        Demo d = new Demo();
        Thread thread1 = new Thread(d,"first thread");
        Thread thread2 = new Thread(d,"second thread");
        thread1.start();
        thread2.start();
    }
    
    Connected to the target VM, address: '127.0.0.1:51427', transport: 'socket'
    first thread10
    second thread9
    first thread8
    second thread7
    second thread6
    first thread5
    second thread4
    first thread3
    first thread2
    second thread2
    first thread1
    second thread1
    second thread0
    first thread-1
    second thread-2
    first thread-3
    second thread-4
    first thread-5
    second thread-6
    first thread-7
    Disconnected from the target VM, address: '127.0.0.1:51427', transport: 'socket'
    
    Process finished with exit code 0
    

    如果我们不想共享类中的变量,那只能初始化2个Demo类,代码如下

    public static void main(String args[]) {
        Demo d1 = new Demo();
        Demo d2 = new Demo();
        Thread thread1 = new Thread(d1,"first thread");
        Thread thread2 = new Thread(d2,"second thread");
        thread1.start();
        thread2.start();
    }
    
    Connected to the target VM, address: '127.0.0.1:65346', transport: 'socket'
    first thread10
    second thread10
    first thread9
    second thread9
    second thread8
    first thread8
    first thread7
    second thread7
    first thread6
    second thread6
    first thread5
    second thread5
    first thread4
    second thread4
    first thread3
    second thread3
    first thread2
    second thread2
    first thread1
    second thread1
    Disconnected from the target VM, address: '127.0.0.1:65346', transport: 'socket'

    2.继承Thread类

    前面我们通过初始化Thread类的方式创建线程,那我们是否可以新建一个类继承Thread类,然后创建线程呢,那肯定是可以的

    测试代码如下

    class Demo extends Thread{
    
        public void run() {
            System.out.println(Thread.currentThread().getName());
    
        }
    }
    
    public static void main(String args[]) {
        Demo d = new Demo();
        Thread thread1 = new Thread(d,"create thread by extends Thread");
        thread1.start();
    }
    
    Connected to the target VM, address: '127.0.0.1:64623', transport: 'socket'
    create thread by extends Thread
    Disconnected from the target VM, address: '127.0.0.1:64623', transport: 'socket'

    3.实现callable接口

    A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call. The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.(返回结果并可能抛出异常的任务。实现者定义了一个不带参数的方法,称为call。 Callable接口与Runnable接口类似,两者都是为其实例可能由另一个线程执行的类设计的。然而,Runnable不返回结果,也不能抛出检查异常。)

    我们查看jdk中callable类的注释,可以知道几个关键的信息

    1.Callable接口和Runnable接口类似,都是为其他线程执行实例而设计的

    2.Callable可以接受结果

    3.Callable可以检查异常

    通过jdk的FutureTask类,我们可以看到其实现了RunableFuture接口,然后这个接口是继承的Runable

    我们来看一下他的源码

    我们可以通过这个方法来实例化FutureTask

    Creates a FutureTask that will, upon running, execute the given Callable. Params: callable – the callable task Throws: NullPointerException – if the callable is null

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

    然后通过get方法获取返回结果

    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

    Returns result or throws exception for completed task. Params: s – completed state value

    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }

    测试代码如下

    class Demo implements Callable{
    
        @Override
        public Object call() throws Exception {
            int sum=0;
            for(int i=0;i<10;i++){
                sum=sum+i;
                Thread.sleep(300);
            }
            System.out.println("sum:"+sum);
            return sum;
        }
    }
    
    
    public static void main(String args[]) throws Exception{
    
        System.out.println("time1:"+new Date());
        Demo d = new Demo();
        FutureTask futureTask = new FutureTask(d);
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println("time2:"+new Date());
        Object sum = futureTask.get(5,TimeUnit.SECONDS);
        System.out.println("time3:"+new Date());
        System.out.println(sum);
    
    }
    
    Connected to the target VM, address: '127.0.0.1:60755', transport: 'socket'
    time1:Fri Mar 11 17:54:19 CST 2022
    time2:Fri Mar 11 17:54:19 CST 2022
    sum:45
    time3:Fri Mar 11 17:54:22 CST 2022
    45
    Disconnected from the target VM, address: '127.0.0.1:60755', transport: 'socket'

    我们可以发现time2和time3之间间隔了3s,然后获得了结果

    4.使用线程池创建线程

    线程池创建线程的优点

    Thread pools address two different problems: they usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks. Each ThreadPoolExecutor also maintains some basic statistics, such as the number of completed tasks.(线程池解决两个不同的问题:它们通常在执行大量异步任务时提高性能,因为减少了每个任务的调用开销,并且它们提供了一种方法来限制和管理执行任务集合时消耗的资源(包括线程)。每个ThreadPoolExecutor还维护一些基本的统计信息,比如完成任务的数量。)

    1.使用ThreadPoolExecutor创建线程.这种方式比较灵活

    Params:

    • corePoolSize – the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set
    • maximumPoolSize – the maximum number of threads to allow in the pool
    • keepAliveTime – when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.
    • unit – the time unit for the keepAliveTime argument
    • workQueue – the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.
    • threadFactory – the factory to use when the executor creates a new thread
    • handler – the handler to use when execution is blocked because the thread bounds and queue capacities are reached
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

    下面我们来测试一下,这里使用callable,当然也可以使用runnable

    class Demo implements Callable{
    
        @Override
        public Object call() throws Exception {
            int sum=0;
            for(int i=0;i<10;i++){
                sum=sum+i;
                Thread.sleep(300);
            }
            System.out.println("sum:"+sum);
            return sum;
        }
    }
    
        public static void main(String args[]) throws Exception{
    
            ThreadPoolExecutor pool = new ThreadPoolExecutor(10,20,60L,TimeUnit.SECONDS,new SynchronousQueue<>(), new ThreadFactoryBuilder().setNameFormat("test thread pool").build(),new ThreadPoolExecutor.AbortPolicy());
            Demo d = new Demo();
            Future f = pool.submit(d);
            System.out.println("当前时间:"+new Date());
            Object result = f.get(5L,TimeUnit.SECONDS);
            System.out.println("当前时间:"+new Date()+"==结果:"+result);
        }
        
    当前时间:Mon Mar 14 11:28:42 CST 2022
    sum:45
    当前时间:Mon Mar 14 11:28:45 CST 2022==结果:45

    2.使用Executors创建线程池

    这种方法比较简单,其实就是对上面的方法进行了一些封装,建议使用上面的方法,因为可以看到具体的参数

    Executorst提供了几个常见构造方法

    • newFixedThreadPool--
    • newSingleThreadExecutor
    • newCachedThreadPool
    • newScheduledThreadPool

    我们来找一个这个类的构造参数看一下

    Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.
    Params:
    nThreads – the number of threads in the pool
    Returns:
    the newly created thread pool
    Throws:
    IllegalArgumentException – if nThreads <= 0

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

    测试一下

    class Demo implements Runnable{
    
        @Override
        public void run() {
            int sum=0;
            for(int i=0;i<10;i++){
                sum=sum+i;
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("sum:"+sum);
    
        }
    }
    
        public static void main(String args[]) throws Exception{
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            Demo d = new Demo();
            executorService.submit(d);
        }
        
    Connected to the target VM, address: '127.0.0.1:55962', transport: 'socket'
    sum:45
    Disconnected from the target VM, address: '127.0.0.1:55962', transport: 'socket'

    展开全文
  • 线程的三种创建方式以及区别

    千次阅读 2021-03-07 18:10:39
    这里写目录标题一:创建线程的三种方式1....注意:这种创建线程方式不能再线程池使用 package CreatThread; public class TestMyThread1 { public static void main(String[] args) { //创建创建线程对象MyThread1

    一.继承类Thread的方式

    1.创建一个继承Thread类的子类MyThread,重写run方法(线程执行的代码)
    2.在main方法中创建MyThread类的对象 t ,就是创建了一个线程
    3.t调用start方法启动线程

    package CreatThread;
    public class TestMyThread1 {
        public static void main(String[] args) {
            //创建创建线程对象MyThread1
            MyThread1 t = new MyThread1();
            //t对象调用start方法启动线程
            t.start();
        }
    }
    //创建一个对象继承Thread类
    class MyThread1 extends Thread {
        //重写run()方法,方法类是线程执行的代码
        @Override
        public void run() {
            System.out.println("执行线程任务,可使用线程对象.start()方法开启线程");
        }
    }
    

    二.继承Runnable接口方式

    1.创建一个实现Runnable接口的类Task,重写run方法(线程执行的代码)
    2.在main方法中定义一个Task类的对象 task(相当于线程执行的任务)
    3.定义一个Thread类的对象 t ,将task作为构造方法的参数传入
    4.最后依旧是t调用start方法启动线程

    package CreatThread;
    
    public class Thread2 {
        public static void main(String[] args) {
            Task task = new Task();
            //将任务对象作为参数传递给Thread的构造方法
            Thread t = new Thread(task);
            t.start();
        }
    
    }
    //创建任务对象实现Runnable接口,需要重载run()方法实现需执行的代码
    class Task implements Runnable {
    
        @Override
        public void run() {
            for (int i = 0;i<10;i++){
                System.out.println(Thread.currentThread().getName()+" "+i);
            }
    
        }
    }
    

    三.使用Callable接口创建线程

    1.Callable接口使用了call方法来代替前两种创建线程方式中线程的执行体,也就是使用call方法代替run方法,call方法具有返回值
    2.Java5使用Future接口来代表call方法的返回值,并且为Future接口提供了一个实现类FutureTask
    。FutureTask既实现了Future接口又实现了Runnable接口。
    3.所以FutureTask可以作为Thread构造方法的参数传入来创建线程

    package CreatThread;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    public class Thread3 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            Callable<Integer> callable = new Mycallable();
            FutureTask<Integer> task = new FutureTask<>(callable);
            Thread thread=new Thread(task);
            //线程开始执行
            thread.start();
        }
    
    
    }
    class Mycallable implements Callable<Integer> {
    
        @Override
        public Integer call() throws Exception {
            System.out.println("你好");
            Thread.sleep(1000);
            return 1;
        }
    }
    
    

    四.这三种创建线程的区别

    1.第二种创建线程的方式相比于第一种创建线程的优点:
    a.更适合多线程实行相同任务,可以减少代码量
    b.避免了单继承的局限性
    c.线程和任务分离,提高了程序健壮性
    d.线程池接受Runnable类型任务,不接受Thread类型线程
    2.第三种相比于前两种创建线程的区别:
    使用Callable方式创建线程时,call方法具有返回值。Future封装了call方法的返回值,可以通过FutureTask的对象调用Future接口的一些方法来控制任务。如:V get():调用这个方法可以阻塞主线程直到子线程返回结果。等等。

    如果感觉这篇文章写得还不错,可以给博主点个赞!

    展开全文
  • 线程的4种创建方式及区别

    千次阅读 2020-08-04 16:32:51
    从 1、继承Thread类 2、实现Runnable接口 3、实现Callable接口 4、创建线程池
  • 创建线程几种方式

    千次阅读 2019-04-12 12:07:59
    创建线程的几种方式方式1:通过继承Thread类创建线程 步骤:1.定义Thread类的子类,并重写该类的run方法,该方法的方法体就是线程需要执行的任务,因此run()方法也被称为线程执行体 2.创建Thread子类的实例,...
  • ======创建线程方式====== 继承Thead类,重写run()方法 实现Runnable类,重写run()方法 使用lombda 实现Callable类,重写call()方法 使用线程池 ======停止线程的方式====== 使用stop()方法 使用suspend()和resume()...
  • C++ 创建线程的方法

    千次阅读 2018-10-09 15:35:13
    c++开发过程中,创建线程是必不可少的,今天就给大家说说c++创建线程的方法,主要介绍我常用的2种方法。 第一种:CreateThread HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_...
  • Java创建线程

    千次阅读 多人点赞 2022-04-05 22:49:44
    既然说到线程,在这里就给大家普及一下线程线程(Thread): 是操作系统能够进行运算调度的最小单位。 它被包含在进程之中,是进程中的实际运作单位。 一个线程指的是进程中一个单一顺序的控制流。 ...
  • 【Window】创建线程的3种方式

    千次阅读 2018-11-01 12:43:41
    挂起状态:线程创建后并没有直接执行或是调用函数挂起了线程。被挂起了的线程没有执行的能力,只有调用启动函数了之后才能执行。 执行状态:在线程的时间片内,拥有CPU资源的时候,这是,线程便开始执行。 阻塞状态...
  • 创建线程的四种方式

    千次阅读 2019-11-21 00:29:29
    5.线程池创建线程 1. 线程的创建有四种方式,分别为: 继承Thread类 实现Runnable接口 实现Callable接口 使用Executor框架创建线程池 编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互。...
  • 线程创建常用的四种方式

    千次阅读 2021-03-24 16:28:17
    Java可以用四种方式创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable接口创建线程 3)使用Callable和Future创建线程 4)使用线程池例如用Executor框架 下面让我们分别来看看这四种创建线程的...
  • java创建线程(Thread)的5种方式

    千次阅读 2021-01-16 17:07:50
    java创建线程(Thread)的4种方式方式一:继承于Thread类方式二:实现Runnable接口方式三:实现Callable接口方式四:使用线程池 方式一:继承于Thread类 步骤: 1.创建一个继承于Thread类的子类 2.重写Thread类的...
  • 最近读完了深入理解Java虚拟机大部分理论章节,感觉对JVM内部执行豁然开朗,并且发现并发编程和虚拟机工作也密不可分,现在再系统读一读多线程、并发这块的书籍,以前也学过多线程,不过没有系统看书,图书馆选了一...
  • 线程创建方式和区别 1.继承Thread类 (1)创建Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。 (2)创建了Thread子类的实例,即创建线程对象。...
  • java 创建线程的三种方式、创建线程池的四种方式

    万次阅读 多人点赞 2019-02-23 21:01:44
    java创建线程的三种方式: 继承Thread类创建线程类 实现Runnable接口 通过Callable和Future创建线程 java创建线程池的四种方式: newCachedThreadPool 创建一个可缓存的线程池,如果线程池长度超过处理...
  • 众所周知,我们在创建线程时有四种方法可以用,分别是: 1、继承Thread类创建线程 2、实现Runnable接口创建线程 3、使用Callable和Future创建线程 4、使用线程池创建(使用java.util.concurrent.Executor接口) 其中...
  • C++多线程,多线程创建,std::thread,普通函数/成员函数/仿函数/匿名函数
  • 创建线程的两种方式 二.启动线程start和run的分析   一.创建线程的两种方式  java提供两种创建线程方式: 1.继承Thread private void createThread(){  new MyThread().start(); } private class...
  • C#几种创建线程方式

    千次阅读 2014-08-21 14:35:21
    using System; using System.Threading; namespace MutiThreadSample {  ///  /// 创建线程方式  ///  class CreateThread  {  ///  /// 不带参数的委托  ///  
  • Lambda方式创建线程

    千次阅读 2021-05-24 16:06:00
    Lamdba创建线程,是对匿名内部类创建多线程的简化 由三部分组成: a、一些参数 b、一个箭头 c、一段代码 格式: (参数列表)->{一些重写方法的代码} 解释说明: ():接口中抽象方法的参数列表,...
  • Java创建线程的8种方式

    万次阅读 多人点赞 2018-07-21 21:16:51
    Java创建启动线程的多种方式 1、继承Thread类,重写run()方法 2、实现Runnable接口,重写run() 3、匿名内部类的方式 4、带返回值的线程(实现implements Callable&lt;返回值类型&gt;)————以上3...
  • 线程创建的四种方式

    万次阅读 多人点赞 2018-03-30 14:34:14
    Java可以用四种方式创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable接口创建线程 3)使用Callable和Future创建线程 4)使用线程池例如用Executor框架 下面让我们分别来看看这四种创建线程的...
  • 创建线程有哪些方式

    千次阅读 2019-05-13 16:23:36
    创建线程有哪些方式? 继承Thread类 实现Runnable接口 实现Callable接口,配合FutureTask 线程池 import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util....
  • Java创建线程的四种方式

    万次阅读 多人点赞 2018-07-28 22:10:16
    1.继承Thread类实现多线程  run()为线程类的核心方法,相当于主线程的main方法,是每个线程的入口  a.一个线程调用 两次start()方法将会抛出线程状态异常,也就是的start()只可以被调用一次   b.native生明的...
  • 多线程(一):创建线程和线程的常用方法

    万次阅读 多人点赞 2018-09-01 19:14:23
    一:为什么要学多线程 应付面试 :多线程几乎是面试中必问的题,所以掌握一定的基础知识是必须的。 了解并发编程:实际工作中很少写多线程的代码,这部分代码一般都被人封装起来了,在业务中使用多线程的机会也...
  • C++11创建线程的三种方式

    千次阅读 2019-04-03 08:30:06
    通过类对象创建线程 class CObject { public: void operator ()() { cout << "线程开始运行" << endl; cout << "线程结束运行" << endl; } }; int main() { CObject obj; std::...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,782,178
精华内容 712,871
关键字:

创建线程的方式

友情链接: LED3264HB.rar