如何让N个线程重复顺次打印0,1,2,..N-1?

解决方案 »

  1.   

    public class  Test implements Runnable {
    int i=1;
    @Override
    public synchronized void  run() {
    // TODO Auto-generated method stub
    System.out.println(i++ +"---------"+Thread.currentThread().getName());
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    public static void main(String[] args) {
    Test t = new Test();
    for(int i=0;i<100;i++){
    new Thread(t).start();
    }
    }
    }
      

  2.   

    首先,进程和线程是两个概念;
    其次,问题有歧义。
    1. N个线程,每个线程都分别打印 0~N-1 这N个数。
    2. N个线程,只要打印 0~N-1 这个范围内的数就行。
    3. N个线程,打印的是 0~N-1 范围内的数,但是,要一轮一轮的来,每轮都从 0~N-1 当中取,哪个线程抢到数字就打印哪个,数字不分先后。
    4. N个线程,模拟单个线程输出 0~N-1 这几个数。
      

  3.   

    //按照我理解的意思(3)写的代码
    public class PrintN { private final int N;
    private final Thread[] group;
    private final Object lock = new Object();
    private int number = 0;
    private volatile boolean running = false;

    public PrintN(int N){
    this.N=N;
    this.group = new Thread[N];
    for(int i=0;i<N;i++){
    group[i] = new Printer();
    }
    }
    private int nextNumber(){
    int next = 0;
    synchronized (lock) {
    next = number++;
    if(number>=N){
    number = 0;
    }
    }
    return next;
    }
    class Printer extends Thread{
    public void run(){
    while(running){
    int n = nextNumber();
    System.out.println(Thread.currentThread().getName()+"\t"+n);
    try {
    Thread.sleep(1);
    } catch (InterruptedException e) {break;}
    }
    }
    }
    public void start(){
    if(running==false){
    running=true;
    for(Thread t : group){
    t.start();
    }
    }
    }
    public void stop(){
    if(running){
    running=false;
    }
    }
    public static void main(String[] args) throws InterruptedException {
    PrintN p = new PrintN(10);
    p.start();
    Thread.sleep(5*1000);
    p.stop();
    }}
      

  4.   

    /**
     * 多线程协作问题,每个线程分别打印自己的序号。<p/>
     * 由于是多个线程顺次打印,所以,执行效率没有单个线程的高。
     */
    public class Printer {
    /** 打印令牌,只有拿到令牌的线程才能打印  */
    private final Object printToken = new Object();
    /** 所有的打印线程 */
    private LocalThread [] printThreads;
    /** 执行状态 */
    private volatile boolean running = false;
    /** 创建线程数组,分配各自线程的序号 */
    public Printer(int number){
    printThreads = new LocalThread[number];
    for(int index = 0 ;index<number; index++){
    printThreads[index] = new LocalThread();
    printThreads[index].index = index;
    printThreads[index].token = null;
    }
    }
    /** 开始执行 */
    public void start(){
    if(!running){
    running = true;
    for(LocalThread lt : printThreads){
    lt.start();
    }
    //给第一个线程放置打印令牌,之后,唤醒所有线程。
    printThreads[0].token = printToken;
    synchronized (printToken) {
    printToken.notifyAll();
    }
    }
    }
    /** 停止执行 */
    public void stop(){
    if(running){
    running = false;
    //将所有处于等待状态的线程强制打扰,之后,线程代码抛出异常,结束运行。
    for(LocalThread lt : printThreads){
    lt.interrupt();
    }
    }
    }
    /** 获得下一个应该得到令牌的线程 */
    LocalThread getNextThread(int index){
    if(++index>=printThreads.length || index<0){
    index=0;
    }
    return printThreads[index];
    }

    class LocalThread extends Thread{
    int index;
    Object token;
    public void run(){
    try {
    while(running){
    //查看自己是否获得令牌,如果没有令牌则等待
    synchronized (printToken) {
    while(token==null){
    printToken.wait();
    }
    }
    //进行打印
    print();
    //传递令牌
    synchronized (printToken) {
    LocalThread next = getNextThread(index);
    next.token = printToken;
    this.token = null;
    printToken.notifyAll();
    }
    }
    } catch (InterruptedException e) {
    if(running){
    e.printStackTrace();
    }
    }
    }
    /** 打印操作 */
    protected void print() {
    System.out.println(Thread.currentThread().getName()+'\t'+index);
    }
    } /**
     * 测试用例
     */
    public static void main(String[] args) throws Exception {
    Printer printer = new Printer(10);
    printer.start();
    Thread.sleep(3000);
    printer.stop();
    }}
      

  5.   

    /**
     * 多线程协作问题,每个线程分别打印自己的序号。<p/>
     * 这个代码是改进后的,效率比上一个版本略微高一点点。<br/>
     * 由于是多个线程顺次打印,所以,执行效率依然没有单个线程的高。
     */
    public class Printer {
    /** 所有的打印线程 */
    private LocalThread [] printThreads;
    /** 执行状态 */
    private volatile boolean running = false;
    /** 创建线程数组,分配各自线程的序号 */
    public Printer(int number){
    printThreads = new LocalThread[number];
    for(int index = 0 ;index<number; index++){
    printThreads[index] = new LocalThread();
    printThreads[index].index = index;
    }
    }
    /** 开始执行 */
    public void start(){
    if(!running){
    running = true;
    for(LocalThread lt : printThreads){
    lt.start();
    }
    //唤醒一个线程。
    synchronized (printThreads[0].printLock) {
    printThreads[0].printLock.notify();
    }
    }
    }
    /** 停止执行 */
    public void stop(){
    if(running){
    running = false;
    //将所有处于等待状态的线程强制打扰,之后,线程代码抛出异常,结束运行。
    for(LocalThread lt : printThreads){
    lt.interrupt();
    }
    }
    }
    /** 获得下一个应该得到令牌的线程 */
    LocalThread getNextThread(int index){
    if(++index>=printThreads.length || index<0){
    index=0;
    }
    return printThreads[index];
    }

    class LocalThread extends Thread{
    int index;
    /** 打印锁,每个线程有自己的打印锁,每个线程先等待,被唤醒后进行打印。 */
    final Object printLock = new Object();
    public void run(){
    try {
    while(running){
    //先进入等待状态,等待被唤醒
    synchronized (printLock) {
    printLock.wait();
    }
    //进行打印
    print();
    //唤醒下一个线程
    LocalThread next = getNextThread(index);
    synchronized (next.printLock) {
    next.printLock.notify();
    }
    }
    } catch (InterruptedException e) {
    if(running){
    e.printStackTrace();
    }
    }
    }
    /** 打印操作 */
    protected void print() {
    System.out.println(Thread.currentThread().getName()+'\t'+index);
    }
    } /**
     * 测试用例
     */
    public static void main(String[] args) throws Exception {
    Printer printer = new Printer(10);
    printer.start();
    Thread.sleep(3000);
    printer.stop();
    }}
      

  6.   

    很郁闷的锁方式,但结果和你预期的一样。package test;
    public class Test {
    private static int NUM = 0;
    public static final Object lock = new Object(); public static void main(String[] args) {
    for (int i = 10; i >= 0; i--) {
    new MyThread(i).start();
    }
    synchronized (lock) {
    lock.notifyAll();
    }
    } static class MyThread extends Thread {
    private int num; public MyThread(int num) {
    this.num = num;
    } public void run() {
    while (NUM < num) {
    synchronized (lock) {
    try {
    lock.wait();
    } catch (InterruptedException e) {
    }
    }
    }
    System.out.println(num);
    NUM++;
    synchronized (lock) {
    lock.notifyAll();
    }
    }
    }
    }