精华内容
下载资源
问答
  • java线程如何让一个线程执行?我目前只能是检测到getname()然后用wait()方法。想知道还有没其他方法? ``` public class TicketSale { public static void main(String[] args) { ...
  • 问题:假设当前有四个线程,分别是A,B,C,D四个线程,假设现在设计一个程序,A,B,C,D四个线程输出A,B,C,D,循环十。 当时面试过程中稍微有点紧张,虽然是面试实习生的岗位,可怕的是居然面试了三轮技术面。...

    问题:假设当前有四个线程,分别是A,B,C,D四个线程,假设现在设计一个程序,让A,B,C,D四个线程一次输出A,B,C,D,循环十次。

    当时面试过程中稍微有点紧张,虽然是面试实习生的岗位,可怕的是居然面试了三轮技术面。可能因为海拍客是小独角兽的原因吧。
    好了,言归正传。这本来是一个比较简单的问题,说白了就是线程同步。线程同步的话也就那几种,Synchronized,Lock锁,阻塞队列这些东东。因为是现场面试的,所以要手写出来,但是一上手的时候发现貌似不好写啊,感觉不是那么回事。但是即使没写出来,后面面试也侥幸通过了。可能是因为前面基础知识回答的还行吧,嘿嘿!!

    话不多说,现在让我们看看怎么来实现这个程序吧。以下有五种方式进行实现:

    • 利用主线程的join()或者子线程的run()方法实现。(下面例子以主线程join()为主)
      public static void main(String args[]){
      Thread A = new Thread(new Runnable(){
      public void run(){
      System.out.print(“A”);
      }
      });
      Thread B = new Thread(new Runnable(){
      public void run(){
      System.out.print(“B”);
      }
      });
      Thread C = new Thread(new Runnable(){
      public void run(){
      System.out.print(“C”);
      }
      });
      Thread D = new Thread(new Runnable(){
      public void run(){
      System.out.print(“D”);
      }
      });

    for(int i=0;i<10;i++){
    A.start();A.join();
    B.start();B.join();
    C.start();C.join();
    D.start();D.join();
    }
    }

    我们知道在程序中使用线程一般不会单个创建和销毁,因为单个线程创建比较耗费资源,所以会复用线程,利用线程池来实现。

    • 线程池实现线程顺序执行
      Java通过Executors提供的线程池有四种,分别是
      (1) 单线程化线程池(newSingleThreadExecutor);
      (2) 可控最大并发数线程池(newFixedThreadPool);
      (3) 可回收缓存线程池(newCachedThreadPool);
      (4) 支持定时和周期任务的线程池(newScheduled);

      newSingleThreadExecutor串行执行所有任务,通过submit()提交任务,shutdown()关闭线程池,拒绝新任务。应用于所有任务的执行顺序按照线程提交顺序执行。
      public static void main(String args[]){
      Thread A = new Thread(new Runnable(){
      public void run(){
      System.out.print(“A”);
      }
      });
      Thread B = new Thread(new Runnable(){
      public void run(){
      System.out.print(“B”);
      }
      });
      Thread C = new Thread(new Runnable(){
      public void run(){
      System.out.print(“C”);
      }
      });
      Thread D = new Thread(new Runnable(){
      public void run(){
      System.out.print(“D”);
      }
      });
      static ExecutorService executorservice = Executors.newSingleThreadExecutor();
      for(int i=0;i<10;i++){
      executorservice.submit(A);
      executorservice.submit(B);
      executorservice.submit©;
      executorservice.submit(D);
      }
      executorservice.shutdown();
      }

    • 通过java.util.Concurrent包下的CountDownLatch(倒计数)实现线程顺序执行。
      public static void main(String args[]){
      //初始化倒计数器的初值为1,每次调用countDown()方法,倒计数器会-1,调用await()方法进行阻塞,当倒计数器值为0时唤醒往下执行。
      private static CountDownLatch c1 = new CountDownLatch(1);
      private static CountDownLatch c2 = new CountDownLatch(1);
      private static CountDownLatch c3 = new CountDownLatch(1);

    Thread A = new Thread(new Runnable(){
    public void run(){
    System.out.print(“A”);
    c1.countDown();
    }
    });
    Thread B = new Thread(new Runnable(){
    public void run(){
    c1.await();
    System.out.print(“B”);
    c2.countDown();
    }
    });
    Thread C = new Thread(new Runnable(){
    public void run(){
    c2.await();
    System.out.print(“C”);
    c3.countDown();
    }
    });
    Thread D = new Thread(new Runnable(){
    public void run(){
    c3.await();
    System.out.print(“D”);
    }
    });
    }

    • 通过CyclicBarrier(回环栅栏)使线程顺序执行。回环栅栏可以实现让一组线程等待至某个状态后在全部同时执行。叫做回环的原因是当所有线程释放后,cyclicbarrier可以重用。我们将这个状态称为barrier,当线程中调用CyclicBarrier的await()方法后,线程就处于barrier状态了。

    public static void main(String args[]){

    //new CyclicBarrier(n),n代表当前栅栏中线程个数。
    static CyclicBarrier barrier1 = new CyclicBarrier(2);
    static CyclicBarrier barrier2 = new CyclicBarrier(2);
    static CyclicBarrier barrier3 = new CyclicBarrier(2);

    Thread A = new Thread(new Runnable(){
    public void run(){
    System.out.print(“A”);
    barrier1.await();
    }
    });
    Thread B = new Thread(new Runnable(){
    public void run(){
    barrier1.await();
    System.out.print(“B”);
    barrier2.await();
    }
    });
    Thread C = new Thread(new Runnable(){
    public void run(){
    barrier2.await();
    System.out.print(“C”);
    barrier3.await();
    }
    });
    Thread D = new Thread(new Runnable(){
    public void run(){
    barrier3.await();
    System.out.print(“D”);
    }
    });

    A.start();
    B.start();
    C.start();
    D.start();

    }

    • 通过Sephmore(信号量)使线程顺序执行。Sephmore(信号量)是一个计数信号量,sephmore包含一组许可证,如果需要的话,每个acquire()方法都会阻塞,直到获取一个可用的许可证,每个release()方法都会释放持有许可证的线程,并且归还Sephmore一个可用的许可证,其实sephmore就是对可用的数量进行管理。

    acquire():当前线程尝试去阻塞的获取1个许可证,此过程是阻塞的,当前线程获取了一个可用的许可证,就会停止等待,继续执行。
    release():当前线程释放一个有用的许可证。

    public static void main(String args[]){

    private static Semaphore semaphore1 = new Semaphore(1);
    private static Semaphore semaphore2 = new Semaphore(1);
    private static Semaphore semaphore3 = new Semaphore(1);

    final Thread A = new Thread(new Runnable() {
    @Override
    public void run() {
    System.out.println(“A”);
    semaphore1.release();
    }
    });
    final Thread B = new Thread(new Runnable() {
    @Override
    public void run() {
    semaphore1.acquire();
    System.out.println(“B”);
    semaphore2.release();
    }
    });
    final Thread C = new Thread(new Runnable() {
    @Override
    public void run() {
    semaphore2.acquire();
    System.out.println(“C”);
    semaphore3.release();
    }
    });
    final Thread D = new Thread(new Runnable() {
    @Override
    public void run() {
    semaphore3.acquire();
    System.out.println(“D”);
    }
    });
    }

    展开全文
  • C#线程学习(二) 如何操纵一个线程作者:钢钢 来源:博客园 时间:2008-09-20 阅读:595 下面我们就动手来创建一个线程,使用Thread类创建线程时,只需提供线程入口即可。(线程入口使程序知道该这个线程干什么...

    C#多线程学习(二) 如何操纵一个线程

    作者:钢钢  来源:博客园  时间:2008-09-20  阅读:595 次

    下面我们就动手来创建一个线程,使用Thread类创建线程时,只需提供线程入口即可。(线程入口使程序知道该让这个线程干什么事)

    在C#中,线程入口是通过ThreadStart代理(delegate)来提供的,你可以把ThreadStart理解为一个函数指针,指向线程要执行的函数,当调用Thread.Start()方法后,线程就开始执行ThreadStart所代表或者说指向的函数。

    打开你的VS.net,新建一个控制台应用程序(Console Application),编写完全控制一个线程的代码示例:

    using System;
    using System.Threading;

    namespace ThreadTest
    {
    public class Alpha
    {
    public void Beta()
    {
    while (true)
    {
    Console.WriteLine(
    "Alpha.Beta is running in its own thread.");
    }
    }
    };

    public class Simple
    {
    public static int Main()
    {
      Console.WriteLine(
    "Thread Start/Stop/Join Sample");
    Alpha oAlpha
    = new Alpha();
       file:
    //这里创建一个线程,使之执行Alpha类的Beta()方法
       Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));
       oThread.Start();
      
    while (!oThread.IsAlive)
       Thread.Sleep(
    1);
       oThread.Abort();
       oThread.Join();
       Console.WriteLine();
       Console.WriteLine(
    "Alpha.Beta has finished");
      
    try
       {
         Console.WriteLine(
    "Try to restart the Alpha.Beta thread");
         oThread.Start();
       }
      
    catch (ThreadStateException)
       {
         Console.Write(
    "ThreadStateException trying to restart Alpha.Beta. ");
         Console.WriteLine(
    "Expected since aborted threads cannot be restarted.");
         Console.ReadLine();
       }
      
    return 0;
       }
    }
    }

    这段程序包含两个类Alpha和Simple,在创建线程oThread时我们用指向Alpha.Beta()方法的初始化了ThreadStart代理(delegate)对象,当我们创建的线程oThread调用oThread.Start()方法启动时,实际上程序运行的是Alpha.Beta()方法:

    Alpha oAlpha = new Alpha();

    Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));

    oThread.Start();

    然后在Main()函数的while循环中,我们使用静态方法Thread.Sleep()让主线程停了1ms,这段时间CPU转向执行线程oThread。然后我们试图用Thread.Abort()方法终止线程oThread,注意后面的oThread.Join(),Thread.Join()方法使主线程等待,直到oThread线程结束。你可以给Thread.Join()方法指定一个int型的参数作为等待的最长时间。之后,我们试图用Thread.Start()方法重新启动线程oThread,但是显然Abort()方法带来的后果是不可恢复的终止线程,所以最后程序会抛出ThreadStateException异常。

    主线程Main()函数

    所有线程都是依附于Main()函数所在的线程的,Main()函数是C#程序的入口,起始线程可以称之为主线程。 如果所有的前台线程都停止了,那么主线程可以终止,而所有的后台线程都将无条件终止。 所有的线程虽然在微观上是串行执行的,但是在宏观上你完全可以认为它们在并行执行。

    Thread.ThreadState 属性

    这个属性代表了线程运行时状态,在不同的情况下有不同的值,我们有时候可以通过对该值的判断来设计程序流程。

    ThreadState 属性的取值如下:

    Aborted:线程已停止;

    AbortRequested:线程的Thread.Abort()方法已被调用,但是线程还未停止;

    Background:线程在后台执行,与属性Thread.IsBackground有关;

    Running:线程正在正常运行;

    Stopped:线程已经被停止;

    StopRequested:线程正在被要求停止;

    Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行);

    SuspendRequested:线程正在要求被挂起,但是未来得及响应;

    Unstarted:未调用Thread.Start()开始线程的运行;

    WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态;

    上面提到了Background状态表示该线程在后台运行,那么后台运行的线程有什么特别的地方呢?其实后台线程跟前台线程只有一个区别,那就是后台线程不妨碍程序的终止。一旦一个进程所有的前台线程都终止后,CLR(通用语言运行环境)将通过调用任意一个存活中的后台进程的Abort()方法来彻底终止进程。

    线程的优先级

    当线程之间争夺CPU时间时,CPU 是按照线程的优先级给予服务的。在C#应用程序中,用户可以设定5个不同的优先级,由高到低分别是Highest,AboveNormal,Normal,BelowNormal,Lowest,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal。

    给一个线程指定优先级,我们可以使用如下代码:

    //设定优先级为最低

    myThread.Priority=ThreadPriority.Lowest;

    通过设定线程的优先级,我们可以安排一些相对重要的线程优先执行,例如对用户的响应等等。

    展开全文
  • linux线程编程中,如果线程A创建了线程B,我知道用pthread__ join可以令线程A ...想A必须等待三个线程都退出后再退出,应该怎么做? 连用pthread__join三吗???但是第一次用了pthread__join后,A不就阻塞了吗?
  • 许多论坛已经多次询问过这个问题.但我没有看到适合我的答案.我试图在我的春季批处理实现中实现多线程步骤.>有一个包含100k记录的临时表>希望在每个线程的10个提交间隔300个线程中处理它 – 所以在任何时间点都...

    许多论坛已经多次询问过这个问题.但我没有看到适合我的答案.我试图在我的春季批处理实现中实现多线程步骤.

    >有一个包含100k记录的临时表

    >希望在每个线程的10个提交间隔300个线程中处理它 – 所以在任何时间点都有3000个记录.

    >我定义了一个任务执行器,并在我想要多线程的步骤中引用它

    >我的想法是,首先我将获得线程池大小(10)并用一个velue(可以是1-10)更新thread_id列到每个100k记录.在这种情况下有10个线程和100k记录,所以10k记录将分配一个id – 我正在尝试实现一个stagingsteplistener来执行此操作.

    >为这个临时表写了一个读者.任务执行器将创建10个读者,每个读者必须读取300个不同的记录并处理它们 – 现在我如何传递一个公共ID

    步骤监听器和读取器之间的关系,以便每个线程都有

    它自己的一组记录要处理.

    截至目前,我只有一个JVM.所以我想在Multi Threaded步骤中做这个,而不是考虑基于分区的方法.

    请帮忙……

    我提到了pro spring批处理书并创建了一个临时步骤监听器,它使用作业参数从作业配置xml接受运行ID,如下所示

    class="com.apress.springbatch.statement.listener.StagingStepListener" scope="step">

    value="where jobId is null and processed is null"/>

    我找不到的是这个?这个“run.id”来自哪里.我在书中的任何地方都没有看到.我在我的spring批处理中复制了相同的实现,当我运行它时,我看到异常说run.id是不可识别的.请帮我讲一下如何做到这一点?

    展开全文
  • 许多论坛已经多次询问过这个问题.但我没有看到适合我的答案.我试图在我的春季批处理实现中实现多线程步骤.>有一个包含100k记录的临时表>希望在每个线程的10个提交间隔300个线程中处理它 – 所以在任何时间点都...

    许多论坛已经多次询问过这个问题.但我没有看到适合我的答案.我试图在我的春季批处理实现中实现多线程步骤.

    >有一个包含100k记录的临时表

    >希望在每个线程的10个提交间隔300个线程中处理它 – 所以在任何时间点都有3000个记录.

    >我定义了一个任务执行器,并在我想要多线程的步骤中引用它

    >我的想法是,首先我将获得线程池大小(10)并用一个velue(可以是1-10)更新thread_id列到每个100k记录.在这种情况下有10个线程和100k记录,所以10k记录将分配一个id – 我正在尝试实现一个stagingsteplistener来执行此操作.

    >为这个临时表写了一个读者.任务执行器将创建10个读者,每个读者必须读取300个不同的记录并处理它们 – 现在我如何传递一个公共ID

    步骤监听器和读取器之间的关系,以便每个线程都有

    它自己的一组记录要处理.

    截至目前,我只有一个JVM.所以我想在Multi Threaded步骤中做这个,而不是考虑基于分区的方法.

    请帮忙……

    我提到了pro spring批处理书并创建了一个临时步骤监听器,它使用作业参数从作业配置xml接受运行ID,如下所示

    我找不到的是这个?这个“run.id”来自哪里.我在书中的任何地方都没有看到.我在我的spring批处理中复制了相同的实现,当我运行它时,我看到异常说run.id是不可识别的.请帮我讲一下如何做到这一点?

    展开全文
  • 可以这么理解:一个线程执行一个代码块,个线程可以同时执行多个代码,使用线程能程序效率更高。举个例子,你今天有两件事需要完成,分别是洗衣服和打扫房间,分别来看看单线程和线程如何完成:单线程:先用...
  • python如何实现多线程

    2018-11-04 22:35:00
    一个线程就是一个轻量级进程,线程能我们一次执行多个线程。 python是线程语言,其内置有线程工具包 python中GIL(全局解释器锁)确保一次执行单个线程。一个线程保存GIL并在将其传递给下个线程之前执行一些...
  • 这个问题网上的答案其实很,但是大多不靠谱。 比如推荐使用仅一控制器,但是仅一控制器对线程组无效;比如推荐跨线程组调用,但是...添加一个吞吐量控制器,选择总数计算(Total Executions) 然后把执行...
  • 一般情况下我们的程序从main方法开始执行,也是说只有一个main线程,这样的话我们就只能一做一件事,而多线程的出现,特别是在CPU电脑出现之后,就可以不同的CPU同时执行不同的线程,去做不同的事情。...
  • 一个线程就是一个轻量级进程,线程能我们一次执行多个线程。我们都知道,Python 是线程语言,其内置有线程工具包。threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。 Python 中的 GIL...
  • 控制线程顺序执行

    2018-07-24 11:41:39
     “ABC三个线程如何让AB并发执行完了再顺序执行C?”  “额,不好意思,不清楚唉,我自己回家等通知吧 = =”  再一次感慨过去写过的代码,业务场景不复杂,都没有很对线程的操作,印象中使用过的就是Thread...
  • Java如何终止线程

    2018-02-07 21:14:29
    Java 虚拟机允许应用程序并发地运行多个执行线程线程特点拥有状态,表示线程的状态,同一时刻中,JVM中的某个线程只有种状态;NEW尚未启动的线程(程序运行开始至今一次未启动的线程)RUNNABLE可运行的线程,...
  • 多线程入门知识点

    2020-09-08 09:58:45
    这里需要纠正一个误区,并不是只有多核的处理器会执行多线程,单线程cpu也会执行多线程代码,cpu通过给每个线程分配cpu时间片来实现这个机制。时间片就是cpu给各个线程分配的时间。因为时间片非常短,所以cpu通过...
  • 项目用的是struts1.2,本来我想在我的查询类里面添加一个公共静态变量,然后查询方法执行的结尾来改变这个静态变量的值,之后我有一个线程来监视这个变量,一旦这个变量的值改变,则说明我的查询方法执行结束...
  • 文章目录三个线程T1、T2、T3,如何让他们按顺序执行?synchronized+wait/notifyjoin()LockLock+ConditionSemaphore ...其实这类问题本质上都是线程通信问题,思路基本上都是一个线程执行完毕,阻塞该线程,
  • Win32多线程程序设计--源代码

    热门讨论 2012-04-22 17:09:08
    以一个c++ 对象启动一个线程 256 建立比较安全的critical sections 265 建立比较安全的locks 268 建立可互换(interchangeable)的locks 270 异常情况(exceptions)的处理 274 提要 274 第10章 mfc中的线程 ...
  • 因配置了15秒执行一次调度,如果屏蔽掉scheduler.rescheduleJob这行代码,则每次是一个线程执行,如15:30:00 work_1执行,15:30:15 work_2执行,以此类推;如果不屏蔽,则每次8个线程并发执行,且每个线程执行N多次(N...
  • 线程

    2012-04-28 22:07:37
    线程: 互斥对象: 1:谁拥有谁释放,其他人释放无效 ...4.如何辨别申请到的互斥对象是上一个线程执行出现问题时释放的还是线程没有调用releaseMutex时释放的,或者是正常申请到的即是上一个线程 正常释放的,我
  • c++线程

    2012-04-26 23:24:46
    线程: 互斥对象: 1:谁拥有谁释放,其他人释放无效 ...4.如何辨别申请到的互斥对象是上一个线程执行出现问题时释放的还是线程没有调用releaseMutex时释放的,或者是正常申请到的即是上一个线程 正常释放的,我
  • Win32多线程程序设计--详细书签版

    热门讨论 2012-04-22 16:59:13
    以一个c++ 对象启动一个线程 256 建立比较安全的critical sections 265 建立比较安全的locks 268 建立可互换(interchangeable)的locks 270 异常情况(exceptions)的处理 274 提要 274 第10章 mfc中的线程 ...
  • 这次解决如何让代码在线线程中仅执行一次,这就是所谓的Lazy_initial。 看下上程序的段代码; class LogFile{ public:  LogFile()  {  f.open(“logfile.txt”);  } public:  void Print_string(s...
  • 线程控制 如何让线程停下来 线程让自己停下来,Sleep函数 ...WaitForSingleObject()函数,等待上一个线程执行结束后,再接着执行 int main() { HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, NULL,
  • 【2021.01.03】线程控制

    2021-01-03 18:15:01
    如何让线程停下来? 函数 作用 Sleep 暂停当前线程的执行,直到超时间隔结束。 SuspendThread ...使用 SuspendThread() 函数对一个线程挂起多次,如果需要恢复线程继续执行,线程被挂起几次就需要使用
  • 二、线程安全 1.为什么有线程安全问题? 当个线程同时共享同一个全局变量或静态...线程在执行的时候,必须先获得锁,一只能允许一个线程获得锁,其他线程必须等待,代码执行完后释放锁,其他线程去执行,...
  • 我有许多线程等待一个事件,执行一些操作,然后再次等待该事件。另一个线程将在适当时触发事件。我想不出一种方法来确保每个等待线程在设置事件时触发一。...简而言之:在Python中,如何让一个线程设置一个事件...
  • 如何避免这问题只下图片那多线程呢,求大佬解答 ![执行开始时](https://img-ask.csdn.net/upload/201911/18/1574070381_322798.png) ![执行一段时间后]...
  • 进程是程序的一次执行活动,是动态的。 2. 任务 线程和进程出现的目的都是为了实现任务,只是对象层级不一样。进程是操作系统级别上的并发,线程是进程级别上的并发。 任务实现的三种方式: 进程 单进程+...
  • CPU/进程管理初探 操作系统是管理硬件的,CPU是最主要的...先看一个例子,下面代码无I/O指令执行10000000,而I/O指令执行10000,发现前者用时竟然比后者用时还要短!笔者使用的还是固态硬盘! 显然,I/O...
  • cpu给每个线程分配cpu时间片来执行代码,因为时间片非常短,所以cpu通过不停的切换线程执行我们感觉多个线程是同时执行的。cpu通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务,...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 215
精华内容 86
关键字:

如何让一个线程多次执行