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

Posted fjk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
.......一直交替循环下去

  

 线程的生命周期

以上是关于day11(多线程,唤醒机制,生产消费者模式,多线程的生命周期)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

Android-Java多线程通讯(生产者 消费者)&10条线程对-等待唤醒/机制的管理

多线程之Java中的等待唤醒机制

多线程下的生产者与消费者模式及(notify()与signal()唤醒的使用和区别)

多线程下的生产者与消费者模式及(notify()与signal()唤醒的使用和区别)