按顺序运行Java线程

你将如何顺序执行三个线程? 例如。 Thread1,Thread2,Thread3。 无法将一个Thread的引用传递给另一个并从run()方法调用。

所以代码应该是这样的:

Thread1.start(); Thread2.start(); Thread3.start(); 

应该是

  Printing Thread1 Printing Thread2 Printing Thread3 

这可以通过使用ThreadPoolExecutor并使用阻塞队列来实现,但即便这样也不是可接受的答案。

在java.util.concurrent包中使用ExecutorService 。 更确切地说,使用Executors.newSingleThreadExecutor();

你可以使用Executors.newSingleThreadExecutor() ,但严格来说这只启动一个 Thread ,所以可能不是预期的解决方案。

使用Thread类的最简单的解决方案:

 Thread1.start(); Thread1.join(); Thread2.start(); Thread2.join(); Thread3.start(); Thread3.join(); 

(为清楚起见,我省略了exception处理, Thread.join()可以抛出InterruptedException

最简单的答案是

 Thread1.run(); Thread2.run(); Thread3.run(); 

不切实际的问题是他们经常有一个无法解释的答案。 ;)

拥有线程的重点是同时运行它们。 如果您根本不这样做,请不要使用线程。

你可能会说; 你不能调用run()方法,在这种情况下你不能使用ThreadPoolExecutor,因为它为你调用run()方法。 即那是submit()最终做的事情。

编辑:结果是完全确定的,因为有一个涉及的线程是不可靠的。

 static class PrintThread extends Thread { public PrintThread(String name) { super(name); } @Override public void run() { for (int i = 0; i < 100; i++) System.out.println(getName() + ": " + i); } } public static void main(String args[]) { Thread thread1 = new PrintThread("A"); Thread thread2 = new PrintThread("B"); Thread thread3 = new PrintThread("C"); thread1.run(); thread2.run(); thread3.run(); } 

打印

 A: 0 A: 1 .. deleted .. C: 98 C: 99 

正如所料。

由于这是一个面试问题,他们正在寻找具体的知识,而不是“以这种方式做得更好”答案。 似乎他们可能会在解决方案之后找出解决方案,直到他们得到他们想要的答案。

他们想知道你是否可以自己实现线程间通信。 但是他们不希望你以简单的方式去做(提供线程参考)。 否则,你可以做thread.join()

所以让所有三个线程都获取一些共享内存(同步静态类)。 让每个线程检查一个public static int nextThread() 。 在成功比较它们是下一个线程后,它们应该完成它们的工作并使用要处理的下一个线程的值更新public static setNextThread(int value)

关键是要以线程安全的方式做到这一点; 但是,如果您可以保证唯一的线程标识符并确保没有两个线程具有相同的标识符,您可以(通过仔细编码)甚至设法在没有同步的情况下执行此操作。

如果它与调用这些线程的各种方式无关,理论上,它们应该使用获取常见的sempahore ,并在完成打印时释放它。
JDK有一个内置的信号量 。

可以使用ExecutorService按顺序执行线程。 找到下面的例子。

 public class SeqThread { public static void main(String[] arg) { new SeqThread().execute(); } public void execute() { try { ExecutorService executor = Executors.newFixedThreadPool(1); executor.submit(R); executor.submit(R2); executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } Runnable R = new Runnable() { @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<10;i++) { System.out.println("In Thread One "+i); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; Runnable R2 = new Runnable() { @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<10;i++) { System.out.println("In Thread Two="+i); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; } 

强制线程以有序的方式运行就像杀死multithreading的概念一样,它更像是单线程程序的子例程执行。 作为面试问题所以一切都好。 这是一个用4个而不是50个线程测试逻辑的程序 –

 public class Outer { private Thread[] jobs; private String[] names; private int indx; public Outer(int numOfThreads) { jobs = new Thread[numOfThreads]; names = new String[numOfThreads]; indx = numOfThreads - 1; } class Inner implements Runnable { public void run() { while (true) { if (names[indx].equals(Thread.currentThread().getName())) { indx--; break; } else { try { Thread.sleep(20); } catch(InterruptedException ie) {} } } // now current thread will join behind the previous one.. if (indx >= 0) try { jobs[indx].join(); } catch(InterruptedException ie) {} /***** YOUR ACTUAL CODE GOES FROM HERE *****/ // at last check is it working ? System.out.println(Thread.currentThread().getName()); } } public void f() { Inner target = new Inner(); // initializing all threads.. for (int i = 0; i < jobs.length; jobs[i++] = new Thread(target)); for (int i = 0; i < names.length; names[i] = jobs[i++].getName()); // checking name of threads.. for (int i = 0; i < names.length; System.out.println(names[i++])); System.out.println(); // now we start all threads.. for (int i = 0; i < jobs.length; jobs[i++].start()); } public static void main(String[] args) { new Outer(50).f(); // testing logic not with 4 but 50 threads.. } } 

您可以在那里找到所有内容: http : //download.oracle.com/javase/tutorial/essential/concurrency/index.html

特别是读取线程之间的通知和同步。

PS请记住,即使你通过面试,你仍然需要工作! 🙂

(好吧,我会给出一些提示:看看像Object.wait()Object.notifyAll()这样的方法的描述它是最简单但也非常有用的机制)

newSingleThreadExecutor。 单线程执行程序创建一个工作线程来处理任务,如果它意外死亡则替换它。 保证任务按照任务队列(FIFO,LIFO,优先级顺序)强加的顺序依次处理。

这可能是一个棘手的问题。 也许他们不想听到这个特定问题的解决方案,但希望您回到问题的根源并提出更好的解决方案。

我使用了基本的线程通信模型,它也可以更简化。 假设你有3个线程,一个是打印0,第二个是打印奇数,第三个是打印偶数liker这个01 02 03 04 05 ….

 public class app{ int status=0; public static void main(String[] args) throws InterruptedException{ app obj = new app(); Thread t1 = new Thread(new print(obj,0)); Thread t2 = new Thread(new print(obj,1)); Thread t3 = new Thread(new print(obj,2)); t1.start();t2.start();t3.start(); } } class print implements Runnable{ app obj; int a; public print(app obj, int a) { this.obj=obj; this.a=a; } @Override public void run() { try{ if(a==0){ synchronized(obj){ for (int i = 0; i < 21; i++) { while(obj.status!=0 && obj.status!=3){ obj.wait(); } System.out.print(0); if(obj.status==0)//even sets status to 0 so next one is odd obj.status=1; else//odd sets status to 3 so next one is even obj.status=2; obj.notifyAll(); } } } else if(a%2!=0){ synchronized (obj) { for (int i = 0; i < 11; i++) { while(obj.status!=1){ obj.wait(); } System.out.print(a); a+=2; obj.status=3; //3 decides 0 came after odd, so next one //after zero is even obj.notifyAll(); } } } else{ synchronized (obj) { for (int i = 0; i < 11; i++) { while(obj.status!=2){ obj.wait(); } System.out.print(a); a+=2; obj.status=0; obj.notifyAll(); } } } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 
 public static void main(String[] args)throws InterruptedException { MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r,"A"); Thread t2 = new Thread(r,"B"); Thread t3 = new Thread(r,"C"); t1.start(); Thread.sleep(1000); t2.start(); Thread.sleep(1000); t3.start(); }