Java学习-多线程交互

1-生产者消费者问题

1. 使用来存放数据
  1.1 把栈改造为支持线程安全
  1.2 把栈的边界操作进行处理,当栈里的数据是0的时候,访问pull的线程就会等待。 当栈里的数据是200的时候,访问push的线程就会等待
2. 提供一个生产者(Producer)线程类,生产随机大写字符压入到堆栈
3. 提供一个消费者(Consumer)线程类,从堆栈中弹出字符并打印到控制台
4. 提供一个测试类,使两个生产者和三个消费者线程同时运行

  1 package multiplethread;
  2
  3 import java.util.LinkedList;
  4 import java.util.List;
  5
  6 public class Test_Producer_Consumer {
  7     public static class stack {
  8         List<Character> data = new LinkedList<>();
  9
 10         public synchronized void push(Character c) {
 11             if (data.size() < 200) {
 12                 data.add(c);
 13                 this.notify();
 14             } else {
 15                 try {
 16                     this.wait();
 17                 } catch (InterruptedException e) {
 18                     // TODO Auto-generated catch block
 19                     e.printStackTrace();
 20                 }
 21             }
 22         }
 23
 24         public synchronized Character pull() {
 25             if (data.size() > 0) {
 26                 Character c = data.remove(data.size() - 1);
 27                 this.notify();
 28                 return c;
 29             } else {
 30                 try {
 31                     this.wait();
 32                 } catch (InterruptedException e) {
 33                     // TODO Auto-generated catch block
 34                     e.printStackTrace();
 35                 }
 36                 return null;
 37             }
 38
 39         }
 40
 41         public synchronized void print() {
 42             System.out.printf("此时栈s的数据是:" + data + "  一共%d个\n", data.size());
 43         }
 44     }
 45
 46     public static class Producer extends Thread { // 生产者线程类
 47         String name;
 48         stack s;
 49
 50         public Producer(stack s, String name) {
 51             this.s = s;
 52             this.name = "Producer " + name;
 53         }
 54
 55         public void run() {
 56             while (true) {
 57                 Character c = ranChar();
 58                 s.push(c);
 59                 System.out.println(this.name + " 压入:" + c);
 60                 s.print();
 61                 try {
 62                     this.sleep(100);
 63                 } catch (InterruptedException e) {
 64                     // TODO Auto-generated catch block
 65                     e.printStackTrace();
 66                 }
 67             }
 68         }
 69
 70     }
 71
 72     public static class Consumer extends Thread { // 消费者线程类
 73         String name;
 74         stack s;
 75
 76         public Consumer(stack s, String name) {
 77             this.s = s;
 78             this.name = "Consumer " + name;
 79         }
 80
 81         public void run() {
 82             while (true) {
 83                 Character c = s.pull();
 84                 System.out.println(this.name + " 弹出:" + c);
 85                 s.print();
 86                 try {
 87                     this.sleep(100);
 88                 } catch (InterruptedException e) {
 89                     // TODO Auto-generated catch block
 90                     e.printStackTrace();
 91                 }
 92             }
 93         }
 94     }
 95
 96     public static class TestThread { // 专门的测试类
 97         public void run() {
 98             stack s = new stack();
 99             for (int i = 0; i < 2; i++) { // 2个生产者
100                 Producer p = new Producer(s, String.valueOf(i));
101                 p.start();
102             }
103             for (int i = 0; i < 3; i++) { // 3个消费者
104                 Consumer c = new Consumer(s, String.valueOf(i));
105                 c.start();
106             }
107         }
108     }
109
110     public static Character ranChar() { // 生成随机的大写字符
111         int s = (int) ‘A‘;
112         int e = (int) ‘Z‘;
113         int n = e - s + 1;
114         int rnd = (int) (Math.floor(Math.random() * n) + s);
115         return (char) rnd;
116     }
117
118     public static void main(String[] args) {
119         TestThread t = new TestThread();
120         t.run();
121
122     }
123 }

效果图:

原文地址:https://www.cnblogs.com/gilgamesh-hjb/p/12236390.html

时间: 2024-12-09 10:30:45

Java学习-多线程交互的相关文章

Java学习---多线程的学习

基础知识 每个正在系统上运行的程序都是一个进程(process).每个进程包含一到多个线程(thread).进程也可能是整个程序或者是部分程序的动态执行. 线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务. Java对多线程的支持是非常强大的,他屏蔽掉了许多的技术细节,让我们可以轻松的开发多线程的应用程序.Java里面有2个方法实现多线程, 1 继承 Thread类,比如 class M

[Java学习]多线程(207待续)

关于多进程与多线程 使用多进程的目的:提高CPU利用率. 使用多线程的目的:提高应用程序?利用率. 多线程与多进程区别:进程间内存独立:同一个进程的线程间共享"堆内存和方法区内存",栈内存是独立的,一个线程一个栈. JVM原理 Java命令启动JVM虚拟机,等于启动了一个进程,该进程会自动启动一个主线程,然后主线程去调用某个类的main方法,所以main方法执行在主线程中. 单线程中,一个方法调用另一个方法,则这些方法按序压入栈中,此时JVM中只有一个栈. Java中多线程 publi

java学习——多线程

本文内容来源于  历经5年锤练--史上最适合初学者入门的Java基础视频 线程:就是进程中一个负责程序执行的控制单元(执行路径) 每一个线程都有自己运行的内容.这个内容可以称为线程要执行的任务. 多线程好处:解决了多部分同时运行的问题. 多线程的弊端:线程太多回到效率的降低. JVM启动时就启动了多个线程,至少有两个线程可以分析的出来. 1,执行main函数的线程, 该线程的任务代码都定义在main函数中. 2,负责垃圾回收的线程. 如何创建一个线程呢? 创建线程方式一:继承Thread类. 步

JAVA学习---多线程

1.线程概述 2.线程实现(2种方式) 2.1通过Thread子类实现(Run方法.Start方法) //继承Thread的方法开启多线程 public class Demo11_1 extends Thread{ public void run() { //线程运行的程序内容 for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } pub

Java自学-多线程 交互

Java 线程之间的交互 wait和notify 线程之间有交互通知的需求,考虑如下情况: 有两个线程,处理同一个英雄. 一个加血,一个减血. 减血的线程,发现血量=1,就停止减血,直到加血的线程为英雄加了血,才可以继续减血 步骤 1 : 不好的解决方式 故意设计减血线程频率更高,盖伦的血量迟早会到达1 减血线程中使用while循环判断是否是1,如果是1就不停的循环,直到加血线程回复了血量 这是不好的解决方式,因为会大量占用CPU,拖慢性能 package charactor; public c

Java 学习————多线程同步

public class Tongywo { public static void main(String[] args) { // TODO Auto-generated method stub Shangdian0 sd=new Shangdian0(100); Goumai0 no1=new Goumai0(70, sd, "No.1"); Goumai0 no2=new Goumai0(80, sd, "No.2"); no1.start(); no2.st

Java学习——多线程例子:李四王五

package cys; public class Example9_2 { public static void main(String[] args) { // TODO Auto-generated method stub People personal1,personal2; StringBuffer str=new StringBuffer(); personal1 = new People("李四",str); personal2 = new People("王五

Java学习——多线程例子:银行

package cys; public class Example9_3 { public static void main(String[] args) { // TODO Auto-generated method stub Bank bank = new Bank(); bank.setMoney(200); Thread thread1,thread2; thread1=new Thread(bank); thread1.setName("One"); thread2=new

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

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