day11(多线程,唤醒机制,生产消费者模式,多线程的生命周期)

A:进程:

    进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。

B:线程:

    线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

C:简而言之:

    一个程序运行后至少有一个进程,一个进程中可以包含多个线程

线程实现

  实现的两种方式

    继承Thread

public class MyThread extends Thread{
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(getName()+":"+i);
		}
	}
}

  测试类

public class MyThread02 extends Thread {
	@Override
	public void run() {
		MyThread t=new MyThread();//直接创建对象就能创建一个线程
	        t.start();
	}
}

  

    实现Runnable

public class MyThreadImp implements Runnable{
	int num;
	public MyThreadImp(int num){
		this.num=num;
	}
	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName()+num++);
		}
	}
}

  测试类

public class Test01 {
	public static void main(String[] args) {
		MyThreadImp mt=new MyThreadImp(10);
		Thread t=new Thread(mt);
		t.setName("张三");
		t.start();
		Thread t1=new Thread(mt);
		t1.setName("李四");
		t1.start();
	}
}

  

多线程安全问题

  线程的安全性==数据的安全性

      ①是否存在多线程

      ②是否有共享数据

      ③是否有多条语句执行共享数据

  解决办法  synchronized同步锁

eg:

public class MyThread implements Runnable {
	int tickets;
	public MyThread(int tickets) {
		this.tickets = tickets;
	}
	Object o = new Object();
	@Override
	public void run() {
		while (true) {
			synchronized (o) {
				if (tickets > 1) {
					System.out.println(Thread.currentThread().getName() + "-"
							+ tickets--);
				}
			}
		}

	}
}

  测试类

        MyThread mt=new MyThread(100);
		Thread t=new Thread(mt);
		t.setName("窗口1");
		Thread t2=new Thread(mt);
		t2.setName("窗口2");
		Thread t3=new Thread(mt);
		t3.setName("窗口3");
		t.start();
		t2.start();
		t3.start();

  如果不给线程加锁  则会产生数据乱掉,可能会产生-1;结果我们不可预测。

在方法中给加锁,另一种方法则是给方法加锁eg:

public class MyThread01 implements Runnable{
	 static int tickets=100;
	public MyThread01(int tickets) {
		this.tickets = tickets;
	}
	@Override
	public void run() {
		while (true) {
				method01();
		}

	}
	private synchronized void method01() {
		if (tickets >= 1) {
			System.out.println(Thread.currentThread().getName() + "-"
					+ tickets--);
		}
	}
}

  

抢红包案列:

public class MyThread implements Runnable {

	int money;
	int count;

	public MyThread(int money, int count) {
		this.money = money;
		this.count = count;
	}

	@Override
	public void run() {
		// 产生一个随机数
			method();
	}

	private synchronized void method() {
		if (count > 1 && money != 0) {
			Random r = new Random();
			double d = (r.nextInt(money) + 1);
			money -= d;
			System.out.println(Thread.currentThread().getName() + ":" + d);
			count--;
		} else {
			System.out.println(Thread.currentThread().getName() + ":"
					+ money);
		}
	}

}

  测试类

public class Hongbao {
	public static void main(String[] args) {
		MyThread mt=new MyThread(10,3);
		Thread t=new Thread(mt);
		t.setName("张三");
		t.start();
		t.setPriority(10);
		Thread t1=new Thread(mt);
		t1.setName("李四");
		t1.start();
		Thread t2=new Thread(mt);
		t2.setName("李");
		t2.start();
	}
}

  

生产消费者模式:

    解释了多线程唤醒机制(notify()是Object中的方法)

使用多线程中的案列

  产品  由于只是做测试使用 没有写全

public class Student {
	String  name;
	int age;
	boolean flag;
}

  

    生产者 如果消费者没有消费产品 则进行等待 ,只有消费了生产者才会进行生产

public class StThread implements Runnable {
	private Student s;
	public StThread(Student s) {
		this.s = s;
	}
	int x;
	@Override
	public void run() {
		while (true) {
			synchronized (s) {
				if (s.flag) {//如果flag=true;则说明已经有对象了  还没有消费,则进行等待
					try {
						s.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}// 等待
				}
				if (x % 2 != 0) {
					s.name = "赵云";
					s.age = 44;
				} else {
					s.name = "张飞";
					s.age = 22;
				}
				x++;
				s.flag=true;//修改标记
				s.notify();//唤醒
			}
		}
	}
}

  

    消费者  如果消费者没有东西消费 则会进行等待  有了东西,才会进行消费

public class GtThread implements Runnable {
	private Student s;
	public GtThread(Student s) {
		this.s = s;
	}
	@Override
	public void run() {
		while (true) {//保证一直在等待中
			synchronized (s) {
				if (!s.flag) {//flag=false则进行等待  等待学生对象的产生
					try {
						s.wait();//线程等待
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(s.name + ":" + s.age);
				s.flag=false;
				s.notify();
			}
		}
	}
}

  

测试类

public class Test {
	public static void main(String[] args) {
		Student s=new Student();
		StThread st=new StThread(s);
		GtThread gt=new GtThread(s);
		Thread t1=new Thread(st);
		Thread t2=new Thread(gt);
		t1.start();
		t2.start();
	}
}

  输出结果

输出结果:
赵云:44
张飞:22
赵云:44
张飞:22
赵云:44
张飞:22
赵云:44
.......一直交替循环下去

  

 线程的生命周期

时间: 2024-11-01 21:25:15

day11(多线程,唤醒机制,生产消费者模式,多线程的生命周期)的相关文章

Java多线程学习笔记--生产消费者模式

实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前水平只能膜拜,本次只能算学习笔记,为了巩固自己对Java多线程常规知识点的理解,路过大神还望能指导指导.下面一段代码是最常规的生产者消费者的例子: package com.zhanglei.demo; import java.util.ArrayList; import java.util.List

RabbitMQ下的生产消费者模式与订阅发布模式

??所谓模式,就是在某种场景下,一类问题及其解决方案的总结归纳.生产消费者模式与订阅发布模式是使用消息中间件时常用的两种模式,用于功能解耦和分布式系统间的消息通信,以下面两种场景为例: 数据接入 ??假设有一个用户行为采集系统,负责从App端采集用户点击行为数据.通常会将数据上报和数据处理分离开,即App端通过REST API上报数据,后端拿到数据后放入队列中就立刻返回,而数据处理则另外使用Worker从队列中取出数据来做,如下图所示. ??这样做的好处有:第一,功能分离,上报的API接口不关心

生产消费者模式,并不是高并发模式

我为什么说生产消费者模式,并不是高并发模式?因为高并发的关键因素是数据分割,不是通信.生产消费者模式只是一个异步数据通信模式.对并发性能的提高有限. 为什么数据分割对并发性能影响这么大? 首先,我们需要说一说硬件cpu,毕竟软件最后是cpu来执行.我们的目标是让代码性能尽可能的高.更详细的表述,就是让代码最大限度的发挥cpu的性能.现在的电脑.手机都已经全部是多核cpu了.所以,表述就是让代码最大限度的发挥多核cpu的性能.最大限度的发挥多核cpu的性能,需要我们尽可能的保证代码的高并行度.高并

多线程等待唤醒机制之生产消费者模式

上篇楼主说明了多线程中死锁产生的原因并抛出问题--死锁的解放方案,那么在本篇文章,楼主将引用一个KFC生产汉堡,顾客购买汉堡的过程来说明死锁解决方案及多线程的等待唤醒机制. 简单地用一幅图来说明KFC生产汉堡,顾客来消费的过程: 场景分析: 资源类:Hamburger 设置汉堡数据:SetThread(生产者) 获取汉堡数据:GetThread(消费者) 测试类:HamburgerTest 不同种类的线程(生产者.消费者)针对同一资源(汉堡)的操作 当汉堡有存货的时候,汉堡师傅不再生产,顾客可消

多线程的等待唤醒机制之消费者和生产者模式

/** * 等待唤醒之生产者和消费者模型 * 生成者: 创建和添加数据的线程 * 消费者: 销毁和删除数据的线程 * 问题1: 生成者生成数据过快, 消费者消费数据相对慢,不接收数据了, 会造成数据丢失 * 问题2: 消费者消费数据过快, 生成者生成数据相对慢,不发送数据了, 会造成数据被重复读取 * 总结 : 生产数据过快会造成数据丢失 * 生成数据过慢会造成数据被重复读取 * * * wait()和notifyAll()用法: * 1. 必须是同一个对象的wait()和和notifyAll(

多线程:简易版本生产消费者模式纯语言概述

一个消费者,一个生产者,一共就两个线程 首先用最简单的语言描述一下这个模型对象为 资源对象,资源对象包括了生产方法,和消费方法,以及计数器生产者对象,只会生产消费者对象,只会销售生产者.消费者实现了Runnable接口,同时拥有一个资源字段和为资源字段构造函数主函数New了一个资源对象New了一个生产者,消费者分别放入一个Thread中执行,结果很可能生产者执行一半,消费者就来执行了,为了避免这种情况为共享数据部分加入Synchronized关键字,进行同步处理但是还有一个问题,生产者,消费者,

java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样,先定义一个缓冲区: public class ValueObject { public static String value = ""; } 换种写法,生产和消费方法放在一个类里面: public class ThreadDomain41 extends ReentrantLock {

多线程之生产者和消费者模式

package com.git.base.thread.productandconsumer; /** * 核心实现: * 生产者消费者模式: * 生产一个,消费一个,如果生产未被消费,那么就等待消费后再生产 * 如果消费后,没有下一个生产的,就等待生产后在消费 * <p>Title: DoMain.java</p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2016</p&g

死锁解决方式之一生产消费者模式之信号灯法

package Tread; /** * 生产者消费者模式:信号灯法 * wait():等待,释放锁: * notify(); * wait和notify必须和sychronized一同使用: * sleep():抱着锁睡觉: * */ public class Movie { private String pic; private boolean flag = true; // 信号灯 // flag=T:生产生产,消费者等待,生产完成后通知消费: // flag=F:消费者消费,生产者等待,