C# 如何让线程等待到执行完毕才执行下一个循环

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 如何让线程等待到执行完毕才执行下一个循环相关的知识,希望对你有一定的参考价值。

代码段
for(int i=0;i<10;i++)

Thread Run = new Thread(new ThreadStart(this.Start));
Run.Start();

我想这样子
比如说 当i=0的时候 执行
Thread Run = new Thread(new ThreadStart(this.Start));
Run.Start();
等Run这个线程执行完毕后
才进入下一个循环i=1
希望吧代码贴出了~~~~

参考技术A for(int i=0;i<10;i++)

Thread Run = new Thread(new ThreadStart(this.Start));
Run.Start();
Run.join();

追问

错误 1 “System.Threading.Thread”不包含“join”的定义,并且找不到可接受类型为“System.Threading.Thread”的第一个参数的扩展方法“join”(是否缺少 using 指令或程序集引用?)

参考技术B thread有一个join方法,可以阻塞主线程, 参考技术C 弄成全局int j=0 ,在this.Start()最后面 j++
for(int i=0;i<10;)

if(j==i)
Thread.Sleep(2000);
continue;
else
i++;

Thread Run = new Thread(new ThreadStart(this.Start));
Run.Start();
本回答被提问者和网友采纳
参考技术D 我只想说,如果是这样,你何必用多线程呢?

juc包下四大并发工具

juc.CountDownLatch 闭锁

一个线程在等待一组线程后再恢复执行

await()等待其他线程执行完毕

被等待线程执行完毕后计数器-1

如何知道其他线程执行完了?

计数器,若一组线程为,CountDown为5,减到0代表等待线程被全部执行完毕

一次性工具:当Countdown的值减到0的时候再也无法恢复

 

juc内部的代码都是lock体系来实现的

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


// 运动员线程
class CDLTask implements Runnable {
    private CountDownLatch countDownLatch;

    public CDLTask(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"开始跑步");
        try {
            TimeUnit.SECONDS.sleep(1);
            System.out.println(Thread.currentThread().getName()+"到达终点");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(4);
        CDLTask cdlTask = new CDLTask(countDownLatch);
        System.out.println("比赛开始...");
        new Thread(cdlTask,"运动员A").start();
        new Thread(cdlTask,"运动员B").start();
        new Thread(cdlTask,"运动员C").start();
        new Thread(cdlTask,"运动员D").start();
        // 等待所有线程都到达终点后再输出此语句
        countDownLatch.await();
        System.out.println("比赛结束...");
    }
}

技术图片

 


juc.CyclicBarrier  循环栅栏

一组线程同时到达临界点后再恢复执行(先到达临界点的线程会阻塞,直到所有线程都到达临界点)

public CyclicBarrier(int parties, Runnable barrierAction)

当多个线程同时到达临界点时,

随机挑选一个线程执行barrierAction后再同时恢复执行

计数器的值可以恢复

await

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

class CBTask implements Runnable {
    private CyclicBarrier cyclicBarrier;

    public CBTask(CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+
                "正在写入数据...");
        try {
            TimeUnit.SECONDS.sleep(2);
            System.out.println(Thread.currentThread().getName()+
                    "写入数据完毕,等待其他线程写入完毕...");
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println("所有线程均已写入完毕,继续恢复执行...");
    }
}
class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4
                ,() -> {
            System.out.println("当前线程为:"+Thread.currentThread().getName());
        });
        CBTask cbTask = new CBTask(cyclicBarrier);
        for (int i = 0; i < 4; i++) {
            new Thread(cbTask,"写线程"+(i+1)).start();
        }
    }
}

技术图片

 


juc.Exchanger 线程交换器

用于两个线程直线的数据交换,当Exchanger只有一个线程时,该线程会阻塞直到有别的线程
调用exchange进入缓冲区,当前线程与新线程交换数据后同时恢复执行。
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;


class ExchangerDemo {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<>();
        Thread girlThread = new Thread(() -> {
            try {
                String girl = exchanger.exchange("我喜欢你.....");
                System.out.println("女生说:"+girl);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        girlThread.start();
        Thread boyThread = new Thread(() -> {
            System.out.println("女神缓缓步入眼帘...");
            try {
                TimeUnit.SECONDS.sleep(1);
                String boy = exchanger.exchange("我喜欢你!");
                System.out.println("男生说:"+boy);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        boyThread.start();
    }
}

技术图片

 



juc.Semaphore 信号量

acquire() : 尝试占用一个信号量,失败的线程会阻塞直到有新的信号量

release() : 释放一个信号量

acquire(int n) : 尝试占用n个信号量,失败的线程会阻塞直到有新的信号量

release(int n) : 释放n个信号量

 

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;


class SemaphoreTask implements Runnable {
    private Semaphore semaphore;

    public SemaphoreTask(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    @Override
    public void run() {
        try {
            semaphore.acquire(2);
            System.out.println(Thread.currentThread()
                    .getName()+"占用2台设备生产");
            TimeUnit.SECONDS.sleep(2);
            System.out.println(Thread.currentThread()
                    .getName()+"生产完毕,释放设备");
            semaphore.release(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(5);
        SemaphoreTask task = new SemaphoreTask(semaphore);
        for (int i = 0; i < 8; i++) {
            new Thread(task,"工人"+(i+1)).start();
        }
    }
}

技术图片

 

以上是关于C# 如何让线程等待到执行完毕才执行下一个循环的主要内容,如果未能解决你的问题,请参考以下文章

如何实现java主线程等待子线程执行完毕之后再执行

线程的优先级

怎么让当前线程等待另一个线程完成之后再去执行

java主线程等待所有子线程执行完毕在执行(常见面试题)

Java如何判断线程池所有任务是不是执行完毕

C#的 Task,Thread,ThreadPool 之间有啥异同