Java学习之多线程二

Posted Vanguard

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习之多线程二相关的知识,希望对你有一定的参考价值。

1、wait和sleep的区别
  sleep: 不释放锁对象, 释放CPU使用权
  在休眠的时间内,不能唤醒
  wait: 释放锁对象, 释放CPU使用权
  在等待的时间内,能唤醒

2、线程的生命周期(五中状态的切换流程)

   新建(new Thread)

  当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
  例如:Thread  t1=new Thread();

  就绪(runnable)
  线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();

  运行(running)
  线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

  死亡(dead)
  当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

  自然终止:正常运行run()方法后终止

  异常终止:调用stop()方法让一个线程终止运行

  堵塞(blocked)
  由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

  正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。

  正在等待:调用wait()方法。(调用motify()方法回到就绪状态)

  被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)


3、有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池用一个数组int[] arr = {10,5,20,50,100,200,500,800,2,80,300};
创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”,随机从arr数组中获取奖项元素并打印在控制台上,格式如下:

抽奖箱1 又产生了一个 10 元大奖
抽奖箱2 又产生了一个 100 元大奖
//.....

 1 /**
 2  * 抽奖池
 3  * 
 4  * @author vanguard
 5  * 
 6  */
 7 public class PoolThread extends Thread {
 8     //定义抽奖池数组
 9     private int[] arr = { 10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300 };
10     //定义奖金个数
11     private int num = arr.length;
12     //定义标记数组
13     private boolean[] flag = new boolean[num];
14     public void run() {
15         while (true) {
16             synchronized (this) {
17                 if(num > 0) {    
18                     Random r = new Random();
19                     int index = r.nextInt(arr.length);
20                     //如果下标为索引的标记数组为false,代表不重复
21                     if(!flag[index]) {
22                         //将下标下的标记数组设为true,代表已经用过
23                         flag[index] = true;
24                         System.out.println(Thread.currentThread().getName() + "又产生了"
25                                 + arr[index] + "元大奖");
26                         //奖金个数减一
27                         num--;
28                     }
29                 }
30             }
31             
32         }
33     }
34 }
 1 **
 2  * 3、有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池用一个数组int[] arr = {10,5,20,50,100,200,500,800,2,80,300}; 
 3     创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”,随机从arr数组中获取奖项元素并打印在控制台上,格式如下:
 4     
 5     抽奖箱1 又产生了一个 10 元大奖
 6     抽奖箱2 又产生了一个 100 元大奖    
 7     //.....
 8  * @author vanguard
 9  *
10  */
11 public class Demo01 {
12     public static void main(String[] args) {
13         PoolThread pt = new PoolThread();
14         Thread t0 = new Thread(pt);
15         t0.setName("抽奖箱1");
16         Thread t1 = new Thread(pt);
17         t1.setName("抽奖箱2");
18         
19         t0.start();
20         t1.start();
21     }
22 }

 


4、某公司组织年会,会议入场时有两个入口,在入场时每位员工都能获取一张双色球彩票,假设公司有100个员工,利用多线程模拟年会入场过程,
并分别统计每个入口入场的人数,以及每个员工拿到的彩票的号码。线程运行后打印格式如下:
编号为: 2 的员工 从后门 入场! 拿到的双色球彩票号码是: [17, 24, 29, 30, 31, 32, 07]
编号为: 1 的员工 从后门 入场! 拿到的双色球彩票号码是: [06, 11, 14, 22, 29, 32, 15]
//.....
从后门入场的员工总共: 13 位员工
从前门入场的员工总共: 87 位员工

 

 1 /**
 2  * 员工进入会场,获取双色球彩票,统计每位员工的彩票号码
 3  * 前门、后门员工个数
 4  * @author vanguard
 5  *
 6  */
 7 public class Entering implements Runnable {
 8     private int frontNum = 0;
 9     private int backNum = 0;
10     private static int person = 100;
11     
12     public void run() {    
13         while(true) {        
14             synchronized (this) {
15                 String ThreadName = Thread.currentThread().getName();
16                 if(person < 0) {
17                     return;
18                 }
19                 if(person > 0) {
20                     if(ThreadName.equals("前门")) {
21                         frontNum++;
22                         System.out.print("编号为" + (100 - person + 1) + "的员工 从" + ThreadName + " 入场,拿到的双色球彩票号码是:");
23                         person--;
24                         getNum();    
25                     } 
26                     if(ThreadName.equals("后门")) {
27                         backNum++;
28                         System.out.print("编号为" + (100 - person + 1) + "的员工 从" + ThreadName + " 入场,拿到的双色球彩票号码是:");
29                         person--;
30                         getNum();    
31                     } 
32                 }
33                 if(person == 0) {
34                     System.out.println("从前门入场的员工总共: " + frontNum + "位员工");
35                     System.out.println("从后门入场的员工总共: " + backNum + "位员工");
36                     person--;
37                 }
38             }
39         }
40         
41         
42     }
43     
44     public void getNum() {
45         List<Integer> list = new ArrayList<Integer>();
46         for(int i = 0; i < 7; i++) {
47             Random r = new Random();
48             int num = r.nextInt(30) + 1;
49             if(list.contains(num)) {
50                 num = r.nextInt(30) + 1;
51             }
52             list.add(num);
53         }
54         System.out.println(list);
55     }
56 }

 

/**
 * 4、某公司组织年会,会议入场时有两个入口,在入场时每位员工都能获取一张双色球彩票,假设公司有100个员工,利用多线程模拟年会入场过程,
    并分别统计每个入口入场的人数,以及每个员工拿到的彩票的号码。线程运行后打印格式如下:
    编号为: 2 的员工 从后门 入场! 拿到的双色球彩票号码是: [17, 24, 29, 30, 31, 32, 07]
    编号为: 1 的员工 从后门 入场! 拿到的双色球彩票号码是: [06, 11, 14, 22, 29, 32, 15]
    //.....
    从后门入场的员工总共: 13 位员工
    从前门入场的员工总共: 87 位员工
 * @author vanguard
 *
 */
public class Demo02 {
    public static void main(String[] args) {
        Entering e = new Entering();
        Thread t0 = new Thread(e, "前门");
        Thread t1 = new Thread(e, "后门");
        
        t0.start();
        t1.start();
    }
}

 























以上是关于Java学习之多线程二的主要内容,如果未能解决你的问题,请参考以下文章

Java学习之多线程

Java学习之多线程一

java多线程学习之volatile 和synchronized

Java学习之多线程二

Java多线程学习之线程池详解

Java基础学习之-多线程学习知识点的学习