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();
    }
}
时间: 2024-11-09 04:18:47

Java学习之多线程二的相关文章

java学习之数组(二)

学编程吧java数组学习(二)发布了,欢迎大家通过xuebiancheng8.com来访问. 下面接着来分析数组,前面分析了什么是数组,为什么要用数组,下面来分析下如何使用数组 数组和其他数据类型一样,使用前要先定义.如下 int a[];这样就声明了一个数组 a = new int[10];然后为这个数组申请10个大小的空间 a[0] = 1; a[1] = 2; ....等等来为数组 赋值,为数组赋值完成后就可以通过下标来访问数组 当然数组在定义的时候也可以讲上面操作合并即 int a []

【Java学习笔记之二十六】深入理解Java匿名内部类

在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意的事项.如何初始化匿名内部类.匿名内部类使用的形参为何要为final. 一.使用匿名内部类内部类 匿名内部类由于没有名字,所以它的创建方式有点儿奇怪.创建格式如下: new 父类构造器(参数列表)|实现接口() { //匿名内部类的类体部分 } 在这里我们看到使用匿名内部类我们必须要继承一个父类或者

JAVA学习笔记 -- 多线程之共享资源

在多线程程序运行过程中,可能会涉及到两个或者多个线程试图同时访问同一个资源.为了防止这种情况的发生,必须在线程使用共享资源时给资源"上锁",以阻挡其它线程的访问.而这种机制也常常被称为互斥量,本文主要介绍它的两种方式synchronized和Lock . 1.synchronized 当任务要执行被synchronized关键字保护的代码片段的时候,它会检查锁是否可用,然后获取锁,执行代码,释放锁.synchronized也有两种用法: A.synchronized方法 import

Java学习笔记—多线程(java.util.concurrent并发包概括,转载)

一.描述线程的类:Runable和Thread都属于java.lang包 二.内置锁synchronized属于jvm关键字,内置条件队列操作接口Object.wait()/notify()/notifyAll()属于java.lang包 二.提供内存可见性和防止指令重排的volatile属于jvm关键字 四.而java.util.concurrent包(J.U.C)中包含的是java并发编程中有用的一些工具类,包括几个部分: 1.locks部分:包含在java.util.concurrent.

登录模块的进化史,带大家回顾java学习历程(二)

接着前面的登录模块的进化史,带大家回顾java学习历程(一) 继续往下面讲 前面我们去实现登录功能,都是想着要完成这个功能,直接在处理实际业务的类中去开始写具体的代码一步步实现,也就是面向过程的编程. 那么现在我们站在设计的角度上去实现该如何做呢?实际上在项目开发的时候,需求规划和数据库设计好之后,我们开始写代码,往往只用写一些接口出来,接口里面只有一些各个业务对应的空方法,没有具体的实现,在架构师进行接口设计的时候,就已经想好了该功能之后通过实现与调用这个接口肯定是可以实现的,等各个功能相关的

java学习-zxing生成二维码矩阵的简单例子

这个例子需要使用google的开源项目zxing的核心jar包 core-3.2.0.jar 可以百度搜索下载jar文件 也可使用maven添加依赖 <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.2.0</version> </dependency> 最简单的生成二维码的方法,

JAVA学习第二十二课(多线程(二))- (多线程的创建方式一 :继承Thread类)

线程是程序中的执行线程.Java 虚拟机允许应用程序并发地运行多个执行线程. 创建新执行线程有两种方法. 一种方法是将类声明为 Thread 的子类.该子类应重写Thread 类的run 方法.另一种方法是声明实现 Runnable 接口的类.该类然后实现run 方法. 创建线程方式一:继承Thread类 一.创建线程的步骤: 1.定义一个类继承Thread类 2.覆盖Thread中的run()方法 3.直接创建Thread类子类的对象 4.调用start方法开启线程,并调用线程的任务run方法

Java学习笔记—多线程(二)

Java线程常用方法总结 1.join()方法 join -- 让一个线程等待另一个线程完成才继续执行.如A线程线程执行体中调用B线程的join()方法,则A线程被阻塞,知道B线程执行完为止,A才能得以继续执行. public class MyRunnable implements Runnable{ @Override public void run() { for(int i=0;i<5;i++){ System.out.println(Thread.currentThread().getN

java学习笔记 多线程

进程是程序的一次动态执行过程,需要经历代码加载,代码执行,执行完毕的一个完整过程. 多进程操作系统能同时运行多个进程(程序),由于cpu具有备份时机制,所以每个进程都能循环获得自己的cpu时间片.由于cpu执行速度非常快,使得所有程序好像是在"同时运行"一样. 线程是比进程更小的单位,线程是在进程基础上进一步的划分.多线程是指一个进程在执行过程中可以产生多个更小的程序单元,这些更小的程序单元称之为线程.(java在运行中至少会启动两个线程:1,main线程 2,垃圾回收线程) 线程的实