精华内容
下载资源
问答
  • 1.在android中,我们常两种线程交互,分别为UI线程(又叫主线程),还有一种是子线程(Thread,Runnable) 2.主线程:UI线程 ...3.如何判断当前线程执行在主线程还是子线程: booean isMainThread=L

    1.在android中,我们常和两种线程交互,分别为UI线程(又叫主线程),还有一种是子线程(Thread,Runnable)

    2.主线程:UI线程

    2.1从名字看下,UI线程,顾名思义就是和UI交互的线程。UI线程一般处理低耗时的UI操作(5秒以内的耗时),

    常见的有:UI的更新,Toast的弹起。popwin以及dialog的,以及view的操作。

    子线程:目前比较常见的就是网络的请求,必须在子线程操作。还有其他的耗时操作

    3.如何判断当前线程执行在主线程还是子线程:

    booean isMainThread=Looper.myLooper()==Looper.getMainLooper();

    如果当前是子线程,必须执行主线程的操作。可以通过

    Looper.prepare();

    主线程操作

    Toast.make(context,"",int).show();

    Looper.loop();

    还有在子线程通过handler来操作主线程的更新。

    子线程执行主线程也可以通过

    HandlerThread thred=new HandlerThread("threadName");

    thread.start();

    Handler handler=new Handler(hread.loop()){

    handderMsg(Message msg){

     

    }

    };

     

    hander.sendgEmptyMessage(int what);

     

     

    展开全文
  • 工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. ...主动式指主线主动去检测某个标志位, 判断子线程是否已经完成....
    工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了.
    一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线程的流程,  往往需要让主线程指定后, 等待子线程的完成. 这里有几种方式.
    站在 主线程的角度, 我们可以分为主动式和被动式.
    主动式指主线主动去检测某个标志位, 判断子线程是否已经完成. 被动式指主线程被动的等待子线程的结束, 很明显, 比较符合人们的胃口. 就是你事情做完了, 你告诉我, 我汇总一下, 哈哈.
    那么主线程如何等待子线程工作完成呢. 很简单, Thread 类给我们提供了join 系列的方法, 这些方法的目的就是等待当前线程的die. 举个例子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    </div>
    public class Threads {
     
    public static void main(String[] args) {
    SubThread thread = new SubThread();
    thread.start();
    //主线程处理其他工作,让子线程异步去执行.
    mainThreadOtherWork();
    System.out.println("now waiting sub thread done.");
    //主线程其他工作完毕,等待子线程的结束, 调用join系列的方法即可(可以设置超时时间)
    try {
    thread.join();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("now all done.");
    }
     
    private static void mainThreadOtherWork() {
    System.out.println("main thread work start");
    try {
    Thread.sleep(3000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("main thread work done.");
    }
     
    public static class SubThread extends Thread{
    @Override
    public void run() {
    working();
    }
     
    private void working() {
    System.out.println("sub thread start working.");
    busy();
    System.out.println("sub thread stop working.");
    }
     
    private void busy() {
    try {
    sleep(5000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
     
    }
    }
     
    本程序的数据有可能是如下:
    1. main thread work start
    2. sub thread start working.
    3. main thread work done.
    4. now waiting sub thread done.
    5. sub thread stop working.
    6. now all done.
    忽略标号, 当然输出也有可能是1和2调换位置了. 这个我们是无法控制的. 我们看下线程的join操作, 究竟干了什么.
    1
    2
    3
    public final void join() throws InterruptedException {
    join(0);
    }
    这里是调用了
    public final synchronized void join(long millis) 
    方法, 参数为0, 表示没有超时时间, 等到线程结束为止. join(millis)方法里面有这么一段代码:
    1
    2
    3
    while (isAlive()) {
    wait(0);
    }
    说明, 当线程处于活跃状态的时候, 会一直等待, 直到这里的isAlive方法返回false, 才会结束.isAlive方法是一个本地方法, 他的作用是判断线程是否已经执行结束. 注释是这么写的: 

    Tests if this thread is alive. A thread is alive if it has been started and has not yet died.

     
    可见, join系列方法可以帮助我们等待一个子线程的结束.
     
    那么要问, 有没有另外一种方法可以等待子线程结束? 当然有的, 我们可以使用并发包下面的Future模式.
    Future是一个任务执行的结果, 他是一个将来时, 即一个任务执行, 立即异步返回一个Future对象, 等到任务结束的时候, 会把值返回给这个future对象里面. 我们可以使用ExecutorService接口来提交一个线程.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    public class Threads {
     
    static ExecutorService executorService = Executors.newFixedThreadPool(1);
     
    @SuppressWarnings("rawtypes")
    public static void main(String[] args) throws InterruptedException, ExecutionException {
    SubThread thread = new SubThread();
    // thread.start();
    Future future = executorService.submit(thread);
    mainThreadOtherWork();
    System.out.println("now waiting sub thread done.");
    future.get();
    // try {
    // thread.join();
    // } catch (InterruptedException e) {
    // e.printStackTrace();
    // }
    System.out.println("now all done.");
    executorService.shutdown();
    }
     
    private static void mainThreadOtherWork() {
    System.out.println("main thread work start");
    try {
    Thread.sleep(3000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("main thread work done.");
    }
     
    public static class SubThread extends Thread{
    @Override
    public void run() {
    working();
    }
     
    private void working() {
    System.out.println("sub thread start working.");
    busy();
    System.out.println("sub thread stop working.");
    }
     
    private void busy() {
    try {
    sleep(5000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
     
    }
     
    }
     
    这里, ThreadPoolExecutor 是实现了 ExecutorService的方法, sumbit的过程就是把一个Runnable接口对象包装成一个 Callable接口对象, 然后放到 workQueue里等待调度执行. 当然, 执行的启动也是调用了thread的start来做到的, 只不过这里被包装掉了. 另外, 这里的thread是会被重复利用的, 所以这里要退出主线程, 需要执行以下shutdown方法以示退出使用线程池. 扯远了. 
     
    这种方法是得益于Callable接口和Future模式, 调用future接口的get方法, 会同步等待该future执行结束, 然后获取到结果. Callbale接口的接口方法是 V call(); 是可以有返回结果的, 而Runnable的 void run(), 是没有返回结果的. 所以, 这里即使被包装成Callbale接口, future.get返回的结果也是null的.如果需要得到返回结果, 建议使用Callable接口.
     
    通过队列来控制线程的进度, 是很好的一个理念. 我们完全可以自己搞个队列, 自己控制. 这样也可以实现. 不信看代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    public class Threads {
     
    // static ExecutorService executorService = Executors.newFixedThreadPool(1);
    static final BlockingQueue queue = new ArrayBlockingQueue(1);
    public static void main(String[] args) throws InterruptedException, ExecutionException {
    SubThread thread = new SubThread(queue);
    thread.start();
    // Future future = executorService.submit(thread);
    mainThreadOtherWork();
    System.out.println("now waiting sub thread done.");
    // future.get();
    queue.take();
    // try {
    // thread.join();
    // } catch (InterruptedException e) {
    // e.printStackTrace();
    // }
    System.out.println("now all done.");
    // executorService.shutdown();
    }
     
    private static void mainThreadOtherWork() {
    System.out.println("main thread work start");
    try {
    Thread.sleep(3000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("main thread work done.");
    }
     
    public static class SubThread extends Thread{
     
    private BlockingQueue queue;
     
    /**
    * @param queue
    */
    public SubThread(BlockingQueue queue) {
    this.queue = queue;
    }
     
    @Override
    public void run() {
    try{
    working();
    }finally{
    try {
    queue.put(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
     
    }
     
    private void working() {
    System.out.println("sub thread start working.");
    busy();
    System.out.println("sub thread stop working.");
    }
     
    private void busy() {
    try {
    sleep(5000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
     
    }
     
    }
     
    这里是得益于我们用了一个阻塞队列, 他的put操作和take操作都会阻塞(同步), 在满足条件的情况下.当我们调用take()方法时, 由于子线程还没结束, 队列是空的, 所以这里的take操作会阻塞, 直到子线程结束的时候, 往队列里面put了个元素, 表明自己结束了. 这时候主线程的take()就会返回他拿到的数据. 当然, 他拿到什么我们是不必去关心的.
    以上几种情况都是针对子线程只有1个的时候. 当子线程有多个的时候, 情况就不妙了.
    第一种方法, 你要调用很多个线程的join, 特别是当你的线程不是for循环创建的, 而是一个一个创建的时候.
    第二种方法, 要调用很多的future的get方法, 同第一种方法.
    第三种方法, 比较方便一些, 只需要每个线程都在queue里面 put一个元素就好了.但是, 第三种方法, 这个队列里的对象, 对我们是毫无用处, 我们为了使用队列, 而要不明不白浪费一些内存,
    那有没有更好的办法呢?有的, concurrency包里面提供了好多有用的东东, 其中, CountDownLanch就是我们要用的.
    CountDownLanch 是一个倒数计数器, 给一个初始值(>=0), 然后每countDown一次就会减1, 这很符合等待多个子线程结束的场景: 一个线程结束的时候, countDown一次, 直到所有都countDown了 , 那么所有子线程就都结束了.
    先看看CountDownLanch有哪些方法:
    await: 会阻塞等待计数器减少到0位置. 带参数的await是多了等待时间.
    countDown: 将当前的技术减1
    getCount(): 返回当前的计数
    显而易见, 我们只需要在子线程执行之前, 赋予初始化countDownLanch, 并赋予线程数量为初始值.
    每个线程执行完毕的时候, 就countDown一下.主线程只需要调用await方法, 可以等待所有子线程执行结束, 看代码:
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    public class Threads {
     
    // static ExecutorService executorService = Executors.newFixedThreadPool(1);
    static final BlockingQueue queue = new ArrayBlockingQueue(1);
    public static void main(String[] args) throws InterruptedException, ExecutionException {
    int threads = 5;
    CountDownLatch countDownLatch = new CountDownLatch(threads);
    for(int i=0;i<threads;i++){
    SubThread thread = new SubThread(2000*(i+1), countDownLatch);
    thread.start();
    }
    // Future future = executorService.submit(thread);
    mainThreadOtherWork();
    System.out.println("now waiting sub thread done.");
    // future.get();
    // queue.take();
    countDownLatch.await();
    // try {
    // thread.join();
    // } catch (InterruptedException e) {
    // e.printStackTrace();
    // }
    System.out.println("now all done.");
    // executorService.shutdown();
    }
     
    private static void mainThreadOtherWork() {
    System.out.println("main thread work start");
    try {
    Thread.sleep(3000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("main thread work done.");
    }
     
    public static class SubThread extends Thread{
     
    // private BlockingQueue queue;
    private CountDownLatch countDownLatch;
    private long work;
     
    /**
    * @param queue
    */
    // public SubThread(BlockingQueue queue) {
    // this.queue = queue;
    // this.work = 5000L;
    // }
     
    public SubThread(long work, CountDownLatch countDownLatch) {
    // this.queue = queue;
    this.countDownLatch = countDownLatch;
    this.work = work;
    }
     
    @Override
    public void run() {
    try{
    working();
    }finally{
    // try {
    // queue.put(1);
    // } catch (InterruptedException e) {
    // e.printStackTrace();
    // }
    countDownLatch.countDown();
    }
     
    }
     
    private void working() {
    System.out.println(getName()+" sub thread start working.");
    busy();
    System.out.println(getName()+" sub thread stop working.");
    }
     
    private void busy() {
    try {
    sleep(work);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
     
    }
    }
    此种方法也适用于使用 ExecutorService summit 的任务的执行.
    另外还有一个并发包的类CyclicBarrier, 这个是(子)线程之间的互相等待的利器. 栅栏, 就是把大家都在一个地方堵住, 就像水闸, 等大家都完成了之前的操作, 在一起继续下面的操作.
    不过就不再本篇的讨论范围内了.
    EO
    展开全文
  • 工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的场景, 这时候就需要使用线程了. ... 主动式指主线程主动去检测某个标志位, 判断子线程是...

      工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的场景, 这时候就需要使用线程了.

      一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线程的流程,  往往需要让主线程指定后, 等待子线程的完成. 这里有几种方式.

      站在主线程的角度, 我们可以分为主动式被动式.

      主动式指主线程主动去检测某个标志位, 判断子线程是否已经完成. 被动式指主线程被动的等待子线程的结束, 很明显, 比较符合人们的胃口. 就是你事情做完了, 你告诉我, 我汇总一下, 哈哈.

    1.      JoinDemo(主动式)

    目的:等待当前线程的die

    示例:

    package com.test;
    
     
    
    public class JoinDemo {
    
        public static void main(String[] args) throws Exception {
    
            //创建子线程,并启动子线程
    
            Thread subThread = new Thread(new SubThread());
    
            subThread.start();
    
            //主线程处理其他工作,让子线程异步去执行
    
            mainWork();
    
            //主线程其他工作完毕,等待子线程的结束, 调用join系列的方法即可(可以设置超时时间)
    
            subThread.join();
    
            System.out.println("Now all thread done!");
    
        }
    
        private static void mainWork() throws Exception{
    
            System.out.println("Main thread start work!");
    
            //sleep
    
            Thread.sleep(2000L);
    
            System.out.println("Main Thread work done!");
    
        }
    
        /**
    
         * 子线程类
    
         * @author fuhg
    
         */
    
        private static class SubThread implements Runnable{
    
            public void run() {
    
                // TODO Auto-generated method stub
    
                System.out.println("Sub thread is starting!");
    
                try {
    
                    Thread.sleep(5000L);
    
                } catch (InterruptedException e) {
    
                    // TODO Auto-generated catch block
    
                    e.printStackTrace();
    
                }
    
                System.out.println("Sub thread is stopping!");
    
            }
    
        }
    
    }

     

    2.      FutureDemo

      使用并发包下面的Future模式.

      Future是一个任务执行的结果, 他是一个将来时, 即一个任务执行, 立即异步返回一个Future对象, 等到任务结束的时候, 会把值返回给这个future对象里面. 我们可以使用    ExecutorService接口来提交一个线程.(注意:Future.get()为一个阻塞方法)

      示例:

      

    package com.test;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class FutureDemo {
    	//创建一个容量为1的线程池
    	static ExecutorService executorService = Executors.newFixedThreadPool(1);
    	
    	public static void main(String[] args) throws Exception {
    		//创建线程并提交线程,同时获取一个future对象
    		Thread subThread = new Thread(new SubThread());
    		Future future = executorService.submit(subThread);
    		//主线程处理其他工作,让子线程异步去执行
    		mainWork();
    		//阻塞,等待子线程结束
    		future.get(); 
    		System.out.println("Now all thread done!");
    		//关闭线程池
    		executorService.shutdown();
    	}
    	//主线程工作
    	private static void mainWork(){
    		System.out.println("Main thread start work!");
    		try {
    			Thread.sleep(2000L);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		System.out.println("Main Thread work done!");
    	}
    	/**
    	 * 子线程类
    	 * @author fuhg
    	 */
    	private static class SubThread implements Runnable{
    		public void run() {
    			// TODO Auto-generated method stub
    			System.out.println("Sub thread is starting!");
    			try {
    				Thread.sleep(5000L);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			System.out.println("Sub thread is stopping!");
    		}
    	}
    }
    

     

    3.      CountDownDemo

      上面两种情况在线程数为一两个的时候,还可以,如果需要控制的线程数很多的话,再采取这种方式就有点过意不去了。

      第一种方法, 你要调用很多个线程的join, 特别是当你的线程不是for循环创建的, 而是一个一个创建的时候.

      第二种方法, 要调用很多的future的get方法, 同第一种方法.

     

      所以去Concurrent库里面找找看还有什么东东吧。

      CountDownLanch 是一个倒数计数器, 给一个初始值(>=0), 然后每一次调用countDown就会减1, 这很符合等待多个子线程结束的场景: 一个线程结束的时候, countDown一次, 直到所有的线程都countDown了 , 那么所有子线程就都结束了.

      先看看CountDownLanch提供的方法吧

      

      

      await: 会阻塞等待计数器减少到0位置. 带参数的await是多了等待时间.

      countDown: 将当前的计数减1

      getCount(): 返回当前的计数

      显而易见, 我们只需要在子线程执行之前, 赋予初始化countDownLanch, 并赋予线程数量为初始值.

      每个线程执行完毕的时候, 就countDown一下.主线程只需要调用await方法, 可以等待所有子线程执行结束。

      示例:

      

    package com.test;
    
    import java.util.concurrent.CountDownLatch;
    
    public class CountDownDemo {
    
    	public static void main(String[] args) throws Exception {
    		//定义线程数
    		int subThreadNum = 5;
    		//取得一个倒计时器,从5开始
    		CountDownLatch countDownLatch = new CountDownLatch(subThreadNum);
    		//依次创建5个线程,并启动
    		for (int i = 0; i < subThreadNum; i++) {
    			new SubThread(2000*(i+1), countDownLatch).start();
    		}
    		//主线程工作
    		mainWork();
    		//等待所有的子线程结束
    		countDownLatch.await();
    		System.out.println("Main Thread work done!");
    	}
    	private static void mainWork(){
    		System.out.println("Main thread start work!");
    		try {
    			Thread.sleep(2000L);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		System.out.println("Main Thread work done!");
    	}
    	/**
    	 * 子线程类
    	 * @author fuhg
    	 */
    	private static class SubThread extends Thread{
    		
    		private CountDownLatch countDownLatch;
    		private long workTime;
    		
    		public SubThread(long workTime,CountDownLatch countDownLatch){
    			this.workTime = workTime;
    			this.countDownLatch = countDownLatch;
    		}
    		
    		public void run() {
    			// TODO Auto-generated method stub
    			try {
    				System.out.println("Sub thread is starting!");
    				Thread.sleep(workTime);
    				System.out.println("Sub thread is stopping!");
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			} finally {
    				//线程结束时,将计时器减一
    				countDownLatch.countDown();
    			}
    		}
    	}
    }
    

     

     

     

    -----------------------------------------------------end of file ---------------------------------------------------------------------------

      参考:记不得了,不好意思啊。

     

    转载于:https://www.cnblogs.com/jsunday/p/3782874.html

    展开全文
  • 在C#中,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供...

            在C#中,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。

            要实现该功能,基本思路如下:

      (1)、把想对另一线程中的控件实施的操作放到一个函数中,(2)、然后使用delegate代理那个函数,(3)、并且在那个函数中加入一个判断,用 InvokeRequired 来判断调用这个函数的线程是否和控件线程处于同一线程中,如果是则直接执行对控件的操作,否则利用该控件的Invoke或BeginInvoke方法来执行这个代理。示例代码如下:

       using System;
       using System.Collections.Generic;
       using System.Windows.Forms;
       
       using System.Threading;
       
       namespace 子线程操作主线程窗体上的控件
       {
           public partial class frmMain : Form
          {
              /********************** 定义该类的私有成员 **************************/
              
              /// <summary>
              /// 定义一个队列,用于记录用户创建的线程
              /// 以便在窗体关闭的时候关闭所有用于创建的线程
              /// </summary>
              private List<Thread> ChaosThreadList;
      
              /********************** 该类的初始化相关函数 ************************/
                      
              /// <summary>
              /// 窗体的初始化函数,初始化线程队列ChaosThreadList
              /// </summary>
              public frmMain()
              {
                  InitializeComponent();
                  ChaosThreadList = new List<Thread>();
              }
                     
              /// <summary>
              /// 窗体的关闭事件处理函数,在该事件中将之前创建的线程全部终止
              /// </summary>
              /// <param name="sender"></param>
              /// <param name="e"></param>
              private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
              {
                  if (ChaosThreadList.Count > 0)
                  {
                      //编列自定义队列,将所有线程终止
                      foreach (Thread tWorkingThread in ChaosThreadList)
                      {
                          tWorkingThread.Abort();
                      }
                  }
              }        
      
              /**************************** 定义该类的自定义函数 ***********************/
      
              /// <summary>
              /// 定义一个代理
              /// </summary>
              /// <param name="index"></param>
              /// <param name="MSG"></param>
              private delegate void DispMSGDelegate(int index,string MSG);
      
              /// <summary>
              /// 定义一个函数,用于向窗体上的ListView控件添加内容
              /// </summary>
              /// <param name="iIndex"></param>
              /// <param name="strMsg"></param>
              private void DispMsg(int iIndex,string strMsg)
              {
                  if (this.lstMain.InvokeRequired==false)     //如果调用该函数的线程和控件lstMain位于同一个线程内
                  {
                      //直接将内容添加到窗体的控件上
                      ListViewItem lvi = new ListViewItem();
                      lvi.SubItems[0].Text = iIndex.ToString();
                      lvi.SubItems.Add(strMsg);
                      this.lstMain.Items.Insert(0, lvi);
                  }
                  else                                        //如果调用该函数的线程和控件lstMain不在同一个线程
                  {
                      //通过使用Invoke的方法,让子线程告诉窗体线程来完成相应的控件操作
                      DispMSGDelegate DMSGD = new DispMSGDelegate(DispMsg);
      
                      //使用控件lstMain的Invoke方法执行DMSGD代理(其类型是DispMSGDelegate)
                      this.lstMain.Invoke(DMSGD, iIndex, strMsg);
                      
                  }
              }
      
              /// <summary>
              /// 定义一个线程函数,用于循环向列表中添加数据
              /// </summary>
              private void Thread_DisplayMSG()
              {
                  for (int i = 0; i < 10000; i++)
                  {
                      DispMsg(i + 1, "Welcome you : " + (i + 1).ToString());
                      Thread.Sleep(10);
                  }
              }
      
              /******************************* 定义该类的事件处理函数 ********************************/
      
              /// <summary>
              /// 【开始】按钮的单击事件处理函数,新建一个线程向窗体上的ListView控件填写内容
              /// </summary>
              /// <param name="sender"></param>
              /// <param name="e"></param>
             private void btnBegin_Click(object sender, EventArgs e)
             {
                 //创建一个新的线程
                 Thread tWorkingThread = new Thread(Thread_DisplayMSG);
     
                 //将新建的线程加入到自定义线程队列中,以便在窗体结束时关闭所有的线程
                 ChaosThreadList.Add(tWorkingThread);
     
                 //开启线程
                 tWorkingThread.Start();
             }     
     
         }
     } 

    这样子就可以实现用子线程去操作主线程窗体上的控件的内容,同时,又不影响主线程对窗体上其他控件的响应。程序运行截图如下:

    点击[开始]按钮,程序开启一个新的线程,不断向列表中添加新的数据,而同时不会影响主界面对其它控件(例如:文本框)的响应。

    https://www.cnblogs.com/zhoug2020/p/5845926.html

    展开全文
  • 工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是...主动式指主线主动去检测某个标志位, 判断子线程是否已
  • 程序 主线程, , , 脚本的主要控制 .参数 索引, 整数型 ' 初始化一下提交次数完成账号 窗口列表.置标题 (索引 - 1, 5, “”) 窗口列表.置标题 (索引 - 1, 7, “”) .判断循环首 (线程 [索引].运行状态 > 0) ...
  • 工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. ...主动式指主线主动去检测某个标志位, 判断子线程是否已经完成. 被...
  • java 如何实现等待子线程结束

    千次阅读 2016-12-18 20:53:18
    工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了。...主动式指主线主动去检测某个标志位, 判断子线程是否已经完成. 被
  • 高手有什么办法没,如何判断15个线程是否结束。 就是如何<span style="color: red"><span style="font-size: medium">让主线程等待所有子线程执行完毕</span></span> <pre name="code" ...
  •  Handler:发送处理消息(Message),必须定义在主线程中,如果是多个类直接互相调用,需要传递content对象  或通过接口调用。 Message有int静态变量what(判断消息),int静态变量arg1、arg2,静态Object...
  • isAlive()join()的使用我们之前说到,最好让主线程最后结束,在前面的例子中,都是通过调用sleep()方法,让线程睡眠产生时差来实现的,经过足够长时间的延迟以确保所有子线程都先于主线程结束。然而,这不是一个...
  • 网络编程实战 33讲:I/O模型多线程模型实现 盛延敏 main reactor线程是一个acceptor... 主线程如何判断子线程已经完成初始化并启动,而继续执行? 子线程阻塞在dispatch上,一旦事件发生,查找channel_map,找...
  • 2、为了实现断点下载,采用数据库方式记录下载的进度,这样当你将该应用退出后,下次点击下载的时候,程序会去查看该下载链接是否存在下载记录,如果存在下载记录就会判断下载的进度,如何从上次下载的进度继续开始...
  • 如何判断这些线程是否都执行完毕,这里有一点讲究。如果靠主线程自己计数,就有可能在加一的过程中错过了某些 notify。所以需要由子线程完成的时候来给计数器加一。子线程之间是相互异步的,所以要用锁来同步这个...
  • 一个很常见的多线程案例是,我们安排主线程作为分配任务汇总的一方,然后将计算工作切分为多个任务,安排多个线程去计算,最后所有的计算结果由主线程进行汇总。比如,归并排序,字符频率的统计等等。 我们知道...
  • 在网上有很多文章讲述主线程和其他子线程如何交互,传送信息,最终谁来执行处理信息之类的,个人理解是最简单的方法——判断Handler对象里面的Looper对象是属于哪条线程的,则由该线程来执行!    1. 当Handler...
  • 4.3.1 主线程的入口点函数返回 4.3.2 ExitProcess函数 4.3.3 TerminateProcess函数 4.3.4 当进程中的所有线程终止时 4.3.5 当进程终止运行时 4.4 进程 4.5 管理员以标准用户权限运行时 4.5.1 自动提升进程的权限 ...
  • 最新Java面试宝典pdf版

    热门讨论 2011-08-31 11:29:22
    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...
  • Java面试宝典-经典

    2015-03-28 21:44:36
    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...
  • Java面试宝典2010版

    2011-06-27 09:48:27
    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 57、介绍Collection框架的结构 58、Collection框架中实现比较要实现什么接口 59、...
  • Java面试宝典2012版

    2012-12-03 21:57:42
    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 ...
  • Java面试宝典2012新版

    2012-06-26 19:20:00
    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43...
  • java面试宝典2012

    2012-12-16 20:43:41
    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 42 57、介绍Collection框架的结构 47 58、Collection框架中实现比较要实现什么接口 47 ...
  • 56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...
  • Java面试笔试资料大全

    热门讨论 2011-07-22 14:33:56
    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...

空空如也

空空如也

1 2 3
收藏数 43
精华内容 17
关键字:

如何判断子线程和主线程