java多线程编程题

本文章主要通过编码形式实现简单的多线程入门实例

1

/**
 * a 线程睡眠10毫秒 对变量加1
 * b 线程睡眠20毫秒 对变量加1
 * 持续60毫秒
 * 分析:理论上a 线程应该打印6次 b线程应该打印3次
 * 思路:通过变量来做累加
 */

package com.thread.base;

/**
 * a 线程睡眠10毫秒 对变量加1
 * b 线程睡眠20毫秒 对变量加1
 * 持续60毫秒
 * 分析:理论上a 线程应该打印6次 b线程应该打印3次
 * 思路:通过变量来做累加
 */
@SuppressWarnings("all")
public class Thread01 {
   static int num=0;
   static int b=0;
   public static void main(String[] args)throws Exception {
      
       Runnable r1 = new Runnable() {
         @Override
         public void run() {
             num++;
             System.out.println("r1:"+num);
         }
      };
      
      Runnable r2 = new Runnable() {
         @Override
         public void run() {
             num++;
             System.out.println("r2:"+num);
         }
      };
      

      while(true){
         Thread.sleep(10);
         if(b%2==0)new Thread(r2).start();
         new Thread(r1).start();
         b++;
         
         if(b==6)break;
      }
       
      
   }
}

2

/**
 * 启动3个线程:
 * 线程1 打印 1 2 3 4 5
 * 线程2 打印 6 7 8 9 10
 * 线程3 打印 11 12 13 14 15
 * 依次循环 输出到75
 *
 * 思路:使用一个可见变量 做累加让其它线程都能知道
 */

package com.thread.base;

/**
 * 启动3个线程:
 * 线程1 打印 1 2 3 4 5
 * 线程2 打印 6 7 8 9 10
 * 线程3 打印 11 12 13 14 15
 * 依次循环 输出到75
 *
 * 思路:使用一个可见变量 做累加让其它线程都能知道
 */
public class Thread02 {
    
   
   public static void main(String[] args)throws Exception {
      new Thread(new MyRunnable(1)).start();
      new Thread(new MyRunnable(2)).start();
      new Thread(new MyRunnable(3)).start();
      
   }
}
class MyRunnable implements Runnable{
    int threadId;
    static volatile int num=0;
    public MyRunnable(int thredId){
       this.threadId = thredId;
    }
   @Override
   public void run() {
       while(num<75){
         synchronized (Thread02.class) {
            if(num/5%3 +1 ==threadId){
               for (int i = 0; i <5; i++) {
                  System.out.println("线程"+threadId+":"+(++num));
               }
               Thread02.class.notifyAll();
            }
            else{
               try{
                  Thread02.class.wait();
               }
               catch(Exception e){
                  e.printStackTrace();
               }
            }
         }
       }
   }
}

3

/**
 * 启动3个线程
 * 线程1 每一次输入a
 * 线程2 每一次输入b
 * 线程3 每一次输入c
 * 连续3次 要求结果输入是abcabcabc这种连续的
 *
 * 分析:其实是多个线程之间的同步,线程a执行完了才可以执行线程b,b执行完了再可以执行c
 * 线程执行顺序:a<b<c
 * 思路:可以使用一个可见状态变量来作为线程同步的标识
 */

package com.thread.base;

/**
 * 启动3个线程
 * 线程1 每一次输入a
 * 线程2 每一次输入b
 * 线程3 每一次输入c
 * 连续3次 要求结果输入是abcabcabc这种连续的
 *
 * 分析:其实是多个线程之间的同步,线程a执行完了才可以执行线程b,b执行完了再可以执行c
 * 线程执行顺序:a<b<c
 * 思路:可以使用一个可见状态变量来作为线程同步的标识
 */
public class Thread03 {
   public static void main(String[] args)throws Exception {
      Object lock = new Object();
      new Thread(new Run03able(0, 1, lock, "A")).start();
      Thread.sleep(400);
      new Thread(new Run03able(1, 2, lock, "B")).start();
      Thread.sleep(400);
      new Thread(new Run03able(2, 0, lock, "C")).start();
   }
}
class Run03able implements Runnable {
   static volatile int state = 0;//可见状态
   int printFlag;//当前打印的线程标识
   int nextPrintFalg;//下一个可以打印的线程标识
   Object obj;//锁对象
   String printStr;//打印字符串
   
   int count= 3;
   
   public Run03able(int printFalg,int nextPrintFalg,Object obj,String printStr){
      this.nextPrintFalg = nextPrintFalg;
      this.printFlag = printFalg;
      this.obj = obj;
      this.printStr = printStr;
   }
   
   @Override
   public void run() {
       synchronized (Run03able.class) {
          for (int i = 0; i < count; i++) {
             while (state!=printFlag) {
                     try {
                        Run03able.class.wait();
                     } catch (InterruptedException e) {
                         return;
                     }
                 }
             System.out.print(printStr);
             state = nextPrintFalg;
             Run03able.class.notifyAll();
            
          }
         
      }
   }

}


4

/**
 * 启动2个线程
 * 线程a 打印 1 3 5 7 9
 * 线程b 打印 2 4 6 8 10
 * 分析:线程a打印的是奇数 线程b打印的是偶数
 */

package com.thread.base;

/**
 * 启动2个线程
 * 线程a 打印 1 3 5 7 9
 * 线程b 打印 2 4 6 8 10
 * 分析:线程a打印的是奇数 线程b打印的是偶数
 */
public class Thread04 {
   public static void main(String[] args) {
      new Thread(new PrintRunable("a")).start();
      new Thread(new PrintRunable("b")).start();
   }
}


class PrintRunable implements Runnable{
   static volatile int num =0;
   public String threadName;
   public PrintRunable(String threadName){
      this.threadName = threadName;
   }
   @Override
   public void run() {
       synchronized (Thread04.class) {
          while(num<100){
              if(getStr(num).equals(threadName)){
                 for (int i = 0; i < 1; i++) {
                  System.out.println("线程"+threadName+":"+(++num));
                 }
                 Thread04.class.notify();
              }
              else{
                 try {
                    Thread04.class.wait();
               } catch (Exception e) {
                  e.printStackTrace();
               }
              }
          }
      }
   }
   
   public String getStr(int i){
      return i%2==0?"b":"a";
   }
   
}

5

/**
 * 启动2个线程
 * 线程1 打印的是1-52之间的数字
 * 线程2 打印的是A-Z之间的26个字母
 * 结果:输入12a34b56c78d910e...依次类推
 *
 */

package com.thread.base;

/**
 * 启动2个线程
 * 线程1 打印的是1-52之间的数字
 * 线程2 打印的是A-Z之间的26个字母
 * 结果:输入12a34b56c78d910e...依次类推
 *
 */
public class Thread05 {
   public static void main(String[] args) {
      Object obj = new Object();
      NumThread numThread = new NumThread(obj);
      CharThread charThread = new CharThread(obj);
      numThread.start();
      charThread.start();
      
      numThread.stop();
      
   }
}

/**
 * 打印数字的线程
 */
class NumThread extends Thread{

   private Object obj;
   
   public NumThread(Object obj) {
      super();
      this.obj = obj;
   }

   @Override
   public void run() {
       synchronized (obj) {
         for (int i = 1; i <53; i++) {
            System.out.print(i);
            if (i%2==0) {
               //唤醒其它等待的线程
               obj.notifyAll();
               try {
                  //阻塞当前执行的线程
                  obj.wait();
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }
      }
   }
   
}

/**
 * 打印字符的线程
 */
class CharThread extends Thread{
   private Object obj;
   public CharThread(Object obj) {
      super();
      this.obj = obj;
   }
   @Override
   public void run() {
       synchronized (obj) {
         for (int i = 0; i <26; i++) {
            System.out.print((char) ('A' + i));  
            obj.notifyAll();
            try {
               obj.wait();
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
      }
   }
   
}

6

启动多个线程

package com.thread.base;

/**
 * 启动多个线程
 * 2个线程做加法
 * 2个线程做减法
 * 依次输入结果
 */
public class Thread06 {
   public static void main(String[] args) {
      AddSubThread add = new AddSubThread();
      //falg true:add,falg false:sub
      AddThread add1 = new AddThread(add);
      AddThread add2 = new AddThread(add);
      
      SubTread subTread1 = new SubTread(add);
      SubTread subTread2 = new SubTread(add);
      
      new Thread(add1).start();
      new Thread(add2).start();
      new Thread(subTread1).start();
      new Thread(subTread2).start();
   }
}

/**
 * 加法线程和减法线程的封装
 */
class AddSubThread{

   int num=0;
   boolean falg = false;//阻塞标识

   /**
    * 加法操作
    */
   public void add (){
      synchronized (AddSubThread.class) {
         while(falg){
            try {
               AddSubThread.class.wait();
            } catch (Exception e) {
                
            }
         }
         System.out.println("add:"+num++);
         falg = true;
         AddSubThread.class.notifyAll();
      }
   }

   /**
    * 减法操作
    */
   public void sub(){
      synchronized (AddSubThread.class) {
         while(!falg){
            try {
               AddSubThread.class.wait();
            } catch (Exception e) {
                
            }
         }
         System.out.println("sub:"+num--);
         falg = false;
         AddSubThread.class.notifyAll();
      }
   }
}


/**
 * 加法线程
 */
class AddThread implements Runnable{
   private AddSubThread thread;
   public AddThread(AddSubThread thread) {
      super();
      this.thread = thread;
   }
   @Override
   public void run() {
       while(true){
          thread.add();
       }
   }
    
}

/**
 * 减法线程
 */
class SubTread implements Runnable{
   private AddSubThread thread;
   public SubTread(AddSubThread thread) {
      super();
      this.thread = thread;
   }
   @Override
   public void run() {
       while(true){
          thread.sub();
       }
   }
    
   
}

7 一个线程和其它几个线程共同完成任务

package com.thread.pool;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorsTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
            //线程数
        int num = 10;
        //CountDownLatch是一个同步辅助类也可以使用AtomicInteger替代
        CountDownLatch doneSignal = new CountDownLatch(num);
        ExecutorService pool = Executors.newCachedThreadPool();
        for(int i=0;i<num;i++)
        //在未来某个时间执行给定的命令
            pool.execute(new WorkerRunnable(doneSignal, i));
        try {
            doneSignal.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //子线程执行完毕,可以开始后续任务处理了
        System.out.println("所有任务执行完毕");

    }

}

/**
 * 子线程
 */
class WorkerRunnable implements Runnable {
       private final CountDownLatch doneSignal;
       private final int i;
       WorkerRunnable(CountDownLatch doneSignal, int i) {
          this.doneSignal = doneSignal;
          this.i = i;
       }
       public void run() {
          //子线程的任务
          try{
          doWork(i);
          }catch (Exception e) {
            e.printStackTrace();
        }
          //任务执行完毕递减锁存器的计数
          doneSignal.countDown();
       }

       void doWork(int i) {
           System.out.println("这是第"+(i+1)+"个任务");
       }
     }

8 通过多线程之间的协作实现队列机制,通过一个布尔变量

package com.thread.queue;

/**
 * Created by jack on 2018/3/31.
 * 使用多线程模拟生产者和消费者机制
 * 线程a 生产消息
 * 线程b 消费消息
 *
 */
public class ThreadQueue01 {
    public static void main(String[] args) {
        Resource resource = new Resource();
        ProducerThread producerThread = new ProducerThread(resource);
        ConsumerThread consumerThread = new ConsumerThread(resource);

        new Thread(producerThread).start();
        new Thread(consumerThread).start();
    }
}

/**
 * 资源管理类
 * 包括消息生产和消费
 */
class Resource {
    private int num = 0;//资源序号
    private boolean falg = false;//资源标记

    /**
     * 生产消息
     */
    public synchronized void produce(){
        if (falg){
            System.out.println("当前消息没有被消费完,清等待消费完再生产..");
            try {
                wait();
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
        num++;
        System.out.println(Thread.currentThread().getName() + "生产者------------" + num);
        falg = true;
        notifyAll();
    }


    /**
     * 消费消息
     */
    public synchronized void consumer (){
        if (!falg){
            System.out.println("对不起当前没有可消费的消息,清等到消息生产再消费");
            try {
                wait();
            }
            catch (Exception e){

            }
        }
        System.out.println(Thread.currentThread().getName() + "消费者****" + num);
        falg = false;
        notifyAll();
    }

}

/**
 * 生产线程
 */
class ProducerThread implements Runnable{
    private Resource resource;

    public ProducerThread(Resource resource){
        this.resource = resource ;
    }
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            }
            catch (Exception e){

            }
            resource.produce();
        }
    }
}

/**
 * 消费线程
 */
class ConsumerThread implements Runnable{
    private Resource resource;

    public ConsumerThread(Resource resource){
        this.resource = resource ;
    }
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            }
            catch (Exception e){

            }
            resource.consumer();
        }
    }
}

9 通过线程协作实现队列机制

package com.thread.queue;

import java.util.ArrayList;
import java.util.List;

/**
 * 通过共享list的大小 来决定是否阻塞对应线程
 */
public class ThreadQueue02 implements Runnable {
  private String name;
  private List<String> list = new ArrayList<String>();
  private final int size = 10;

  /**
   * 模拟消息的生产
   * @param num
   * @throws Exception
     */
  public void produce(int num) throws Exception {
    while (true) {
      synchronized (list) {
        while (list.size() + num > size) {
          System.out.println(Thread.currentThread().getName()+"生产过剩,等待消费");
          list.wait();
        }
        System.out.println(Thread.currentThread().getName()+"正在生产");
        for (int i = 0; i < num; i++) {
          list.add("hello, world");
        }
        list.notify();
      }
      Thread.sleep(1000);
    }
  }

  /**
   * 模拟消息的消费
   * @throws Exception
     */
  public void consume() throws Exception {
    while (true) {
      synchronized (list) {
        while (list.size() == 0) {
          System.out.println(Thread.currentThread().getName()+"已无产品可消费,等待生产");
          list.wait();
        }
        System.out.println(Thread.currentThread().getName()+"正在消费");
        list.remove(0);
        list.notify();
      }
      Thread.sleep(1000);
    }
  }
  public void setName(String name) {
    this.name = name;
  }

  public void run() {
    try {
      if ("producer".equals(name)) {
        produce(1);
      }
      else {
        consume();
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }


  public static void main(String[] args) {
    try {
      ThreadQueue02 myThread = new ThreadQueue02();
      myThread.setName("producer");
      Thread t1 = new Thread(myThread);
      Thread t4 = new Thread(myThread);
      t1.start();
      t4.start();
      Thread.sleep(1);
      myThread.setName("consumer");
      Thread t2 = new Thread(myThread);
      Thread t3 = new Thread(myThread);
      t2.start();
      t3.start();
    }
    catch (Exception e) {

    }
  }
}

10 

直接使用阻塞队列来模拟生产者和消费者

package com.thread.queue;

import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by jack on 2018/3/31.
 * 直接使用阻塞队列来模拟生产者和消费者
 */
@SuppressWarnings("all")
public class ThreadQueue03 {
    public static void main(String[] args)throws Exception {
        // 声明一个容量为10的缓存队列
        BlockingQueue<String> queue = new LinkedBlockingQueue<String>(10);

        ProducerRunnable producer1 = new ProducerRunnable(queue);
        ProducerRunnable producer2 = new ProducerRunnable(queue);
        ProducerRunnable producer3 = new ProducerRunnable(queue);
        ConsumerRunnable consumer = new ConsumerRunnable(queue);

        // 借助Executors
        ExecutorService service = Executors.newCachedThreadPool();
        // 启动线程
        service.execute(producer1);
        service.execute(producer2);
        service.execute(producer3);
        service.execute(consumer);

        // 执行10s
        Thread.sleep(10 * 1000);
        producer1.stop();
        producer2.stop();
        producer3.stop();

        Thread.sleep(2000);
        // 退出Executor
        service.shutdown();
    }
}

/**
 * 生产线程
 */
class ProducerRunnable implements Runnable{
    private static final int DEFAULT_RANGE_FOR_SLEEP = 1000;
    private BlockingQueue blockingQueue;
    private volatile boolean isRunning = true;
    private static AtomicInteger count = new AtomicInteger();


    public ProducerRunnable(BlockingQueue blockingQueue){
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        String data = null;
        Random r = new Random();
        System.out.println("启动生产者线程");
        try {
            while (isRunning){
                System.out.println("正在生产数据");
                Thread.sleep(r.nextInt(DEFAULT_RANGE_FOR_SLEEP));
                data = "data:" + count.incrementAndGet();
                System.out.println("将数据:" + data + "放入队列...");
                if (!blockingQueue.offer(data, 2, TimeUnit.SECONDS)) {
                    System.out.println("放入数据失败:" + data);
                }
            }
        }
        catch (Exception e){
            Thread.currentThread().interrupt();
        }
        finally {
            System.out.println("退出生产者线程!");
        }
    }

    public void stop() {
        isRunning = false;
    }
}

/**
 * 消费线程
 */
class ConsumerRunnable implements Runnable{
    private static final int DEFAULT_RANGE_FOR_SLEEP = 1000;
    private BlockingQueue blockingQueue;
    volatile  boolean  isRunning = true;


    public ConsumerRunnable(BlockingQueue blockingQueue){
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        System.out.println("启动消费者线程!");
        Random r = new Random();
        try {
            while (isRunning) {
                System.out.println("正从队列获取数据...");
                String data = blockingQueue.poll(2, TimeUnit.SECONDS).toString();
                if (null != data) {
                    System.out.println("拿到数据:" + data);
                    System.out.println("正在消费数据:" + data);
                    Thread.sleep(r.nextInt(DEFAULT_RANGE_FOR_SLEEP));
                } else {
                    // 超过2s还没数据,认为所有生产线程都已经退出,自动退出消费线程。
                    isRunning = false;
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        } finally {
            System.out.println("退出消费者线程!");
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值