11
回答
多线程 排序
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

两个线程,一个线程 输出1,3,5,    另一个线程输出2,4,6   如何 使得最终输出1,2,3,4,5,6

求各位大神,赐教

<无标签>
举报
msgyg
发帖于4个月前 11回/257阅
共有11个答案 最后回答: 3个月前

这就是java两个线程交替执行,实现方法很多种,可以用线程锁:synchronized、Lock  、notify和wait

当然还可以用标记的方法,你可先实现怎么让两个线程交替执行,然后在考虑打印的数据

public class MainTests {
	private static int state = 1;
	public static void main(String[] args) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				int i=0;
				while(true){
					if(state==1 && (i%2)==0){
						System.out.println("A线程:"+i);
						state=2;
					}
					i++;
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		t.start();

		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				int i=0;
				while(true){
					if(state==2 && (i%2)!=0){
						System.out.println("B线程:"+i);
						state=1;
					}
					i++;
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		});
		t2.start();
	}
}

 

共享变量,同步执行插入排序,或者,等待线程运行结束后,再进行二次排序,这里由于已经得到了两个有序序列,可以用选择排序

引用来自“北极心”的评论

public class MainTests {
	private static int state = 1;
	public static void main(String[] args) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				int i=0;
				while(true){
					if(state==1 && (i%2)==0){
						System.out.println("A线程:"+i);
						state=2;
					}
					i++;
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		t.start();

		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				int i=0;
				while(true){
					if(state==2 && (i%2)!=0){
						System.out.println("B线程:"+i);
						state=1;
					}
					i++;
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		});
		t2.start();
	}
}

 

为 北极心提供的 答案 “润色”,要点如下:

  • 两个模拟线程的"睡觉时间" 由 1000 毫秒,改为不到1秒的一个随机产生的毫秒数值。使得事态发展更随机。
  • 鉴于 java 可以有布尔型变量, 将 静态属性 state 改为 boolean 布尔类型
  • 其它代码,稍作相应调整。

”润色“结果如下:

import java.lang.*;

public class MainTest0 {
		
	private static boolean state = true ;
	public static void main(String[] args) {
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				int i=1;
				while(true){
					if(state){
						System.out.println("奇数线程发声: "+i);
						state=!state;
					i+=2;
					}
					try {
						Thread.sleep((int)(1000*Math.random()));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		t1.start();

		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				int i=2;
				while(true){
					if(!state){
						System.out.println("偶数线程发声: "+i);
						state=!state;
					i+=2;
					}
					try {
						Thread.sleep((int)(1000*Math.random()));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		});
		t2.start();
	}
}

 

--- 共有 1 条评论 ---
北极心我也就看了下问题,就随便动手试了下,没想那么多就把代码贴出来了,见笑了,多谢指教! 其实我感觉还是用同步,线程锁(synchronized、Lock 、notify 、wait)来实现比较正规点,我想出此题目的人也是想考你这几个关键字的用法的 4个月前 回复

引用来自“北极心”的评论

这就是java两个线程交替执行,实现方法很多种,可以用线程锁:synchronized、Lock  、notify和wait

当然还可以用标记的方法,你可先实现怎么让两个线程交替执行,然后在考虑打印的数据

场景解释:

  1. 创建一个协调者 ThreadLocker, 它的唯一属性是布尔型的信号旗flag, 通过这面旗,控制在线的线程, OddThread 和 EvenThread, 的数值输出。
  2. 创建 奇数和偶数 两线程。它们都有一个相同的属性:刚创建的协调者 ThreadLocker 对象。 换言之,这个协调者,则成了这两个线程,共享的实体。
  3. 奇数和偶数 两线程的运行内容,都是:最长睡觉 3 秒,然后分别通过协调者的方法,setOdd(int ) 和 setEven(int ) 向共享的 “线程锁” 报告要对应的发出的数值。
  4. 这两个线程,均按照 协调者的信号旗的信号,执行 是否等待 wait() 的命令。
  5. 等待过后,均 反置信号旗信号; 发声; 通知 notify() 对方(那个正在等待的线程) “解锁”。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Random;

class OddThread implements Runnable {  //定义 产生奇数数值的线程
   private static Random generator = new Random();
   private ThreadLocker sharedLocation; // 与 EvenThread 共享的线程锁对象

   // OddThread constructor 奇数线程的构造方法
   public OddThread( ThreadLocker shared ){ 
      sharedLocation = shared; //获取 与 EvenThread 共享的线程锁对象
   } // end OddThread constructor 

   // store values from 1 to 9 in sharedLocation
   public void run(){
      for ( int count = 1; count <= 9; count+=2 ) {  
         try {// 最长睡觉 3 秒, 然后向共享的线程锁报告要发声的奇数数值
            Thread.sleep( generator.nextInt( 3000 ) ); // sleep thread   
            sharedLocation.setOdd( count );// 在共享的线程锁,设置奇数数值
         } // end try
         // if sleeping thread interrupted, print stack trace
         catch ( InterruptedException exception ){
            exception.printStackTrace();
         } // end catch
      } // end for
   } // end method run
} // end class OddThread

class EvenThread implements Runnable { 
   private static Random generator = new Random();
   private ThreadLocker sharedLocation; // 与OddThread共享的线程锁对象

   // constructor
   public EvenThread( ThreadLocker shared ){ //EvenThread的构造方法
      sharedLocation = shared;//获取 与 OddThread 共享的线程锁对象
   } // end EvenThread constructor 构造方法 定义 完

   public void run(){
      for ( int count = 2; count <= 10; count+=2 ){
         // 最长睡觉 3 秒, 然后向共享的线程锁报告要发声的偶数数值
         try  {
            Thread.sleep( generator.nextInt( 3000 ) );    
            sharedLocation.setEven( count); // 在共享的线程锁,设置偶数数值
         } // end try
         // if sleeping thread interrupted, print stack trace
         catch ( InterruptedException exception ){
            exception.printStackTrace();
         } // end catch
      } // end for
   } // end method run
} // end class EvenThread

class ThreadLocker{ // 协调者:线程锁
   private boolean flag = false; // 信号旗, true 等待, false 不等待
   
   // 将要释放的奇数数值,置于线程锁,以便在适当的机会,输出 ("发声")
   public synchronized void setOdd( int value ){// 为 OddThreade 所用
      while ( flag ) { // 信号旗为 true,EvenThread 等待
         try{
            wait();
            } catch ( InterruptedException exception ){
            exception.printStackTrace();
         } // end catch
      } // end while
 
      flag = true;  
      System.out.println( "奇数线程发声: " + value );
      notify(); // 通知等待方(EvenThread),进入运行状态
   } // end method setOdd; 解锁
    
 
   public synchronized void setEven(int value){//为 EvenThreade 所用
      while ( !flag ){ // 信号旗为false,OddThread 等待
         try{
            wait();
         } catch ( InterruptedException exception ){
            exception.printStackTrace();
         } // end catch
      } // end while
      flag = false;
      System.out.println( "偶数线程发声: " + value );     
      notify(); // 通知等待方(OddThread),进入运行状态
   } // end method setEven; 解锁
} // end class ThreadLocker


public class Test{
   public static void main( String[] args ){
// create new thread pool with two threads 创建持有两个线程的线程池
      ExecutorService application = Executors.newFixedThreadPool( 2 );

// 创建 线程锁(ThreadLocker), 用来指挥 奇数/偶数 线程的执行
      ThreadLocker sharedLocation = new ThreadLocker (); 

      try {// try to start OddThread and EvenThread 试图开启奇数/偶数 线程
         application.execute( new OddThread(  sharedLocation ) );
         application.execute( new EvenThread( sharedLocation ) );
      } // end try
      catch ( Exception exception ){
         exception.printStackTrace();
      } // end catch
      application.shutdown();
   } // end main
} // end Test

 

使用数据库,几行就写完了,并且容易阅读。

package iBoxDB;

import iBoxDB.LocalServer.*;

public class Sort {

    public static void main(String[] args) throws Exception {
        final int runTime = 5;

        DB db = new DB(DB.CacheOnlyArg);
        db.getConfig().ensureTable(Num.class, "/Num", "id");
        final AutoBox auto = db.open();

        class NumRunnable implements Runnable {

            int num;
            int rt;

            public NumRunnable(int begin) {
                num = begin;
                rt = runTime;
            }

            @Override
            public void run() {
                while (rt-- > 0) {
                    Num n = new Num();
                    n.id = num;
                    num += 2;
                    auto.insert("/Num", n);
                }
            }

        }

        Thread t1 = new Thread(new NumRunnable(1));
        Thread t2 = new Thread(new NumRunnable(2));
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        for (Num n : auto.select(Num.class, "from /Num order by id")) {
            System.out.println(n.id);
        }
    }

    public static class Num {

        public int id;
    }
}

 

顶部