线程的通信:
分析:
需要两个线程—输入线程,和输出线程,
需要两个任务===输入任务和输出任务
需要一份数据
使用唤醒等待机制实现:wait()/notify()/notifyAll()等
实现:打印机打印–不断地输入不断地输出
分析:需要输入任务和输出任务共用一把锁,保证两个任务之间是同步的
给两个任务加一把锁,可以是this或Object.class
不建议使用Object.class原因:由于Object.class的范围太大了,会造成不必要的错误
使用this最合适,因为他只被两个线程共享
注意:只给一个线程加锁,无法实现两个线程的同步;
public static void main(String[] args) {
//1.创建数据类对象
Des des = new Des();
//2.创建任务类对象
Input input = new Input(des);
Output output = new Output(des);
//3.创建线程
Thread inputThread = new Thread(input);
Thread outputThread = new Thread(output);
//4.开启线程
inputThread.start();
outputThread.start();
}
}
//创建输入任务
class Input implements Runnable{
Des des;
public Input() {
super();
// TODO Auto-generated constructor stub
}
public Input(Des des) {
super();
this.des = des;
}
@Override
public void run() {
// TODO Auto-generated method stub
int i = 0;
while(true) {
synchronized (des) {
if(i == 1) {
des.name = "凤姐";
des.sex = "男";
}else {
des.name = "芙蓉姐姐";
des.sex = "女";
}
i = (i+1)%2;
}
}
}
}
//创建输出任务
class Output implements Runnable{
Des des;
public Output(Des des) {
super();
this.des = des;
}
public Output() {
super();
// TODO Auto-generated constructor stub
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
synchronized (des) {
System.out.println(des);
}
}
}
}
//创建数据类
class Des{
String name;
String sex;
@Override
public String toString() {
return "Des [名字=" + name + ", 性别=" + sex + "]";
}
}
public static void main(String[] args) {
//1.创建数据类对象
Des1 des = new Des1();
//2.创建任务类对象
Input1 input = new Input1(des);
Output1 output = new Output1(des);
//3.创建线程
Thread inputThread = new Thread(input);
Thread outputThread = new Thread(output);
//4.开启线程
inputThread.start();
outputThread.start();
}
}
//创建输入任务
class Input1 implements Runnable{
Des1 des;
public Input1() {
super();
// TODO Auto-generated constructor stub
}
public Input1(Des1 des) {
super();
this.des = des;
}
@Override
public void run() {
// TODO Auto-generated method stub
int i = 0;
while(true) {
if(i == 0) {
des.setData("凤姐", "男");
}else {
des.setData("芙蓉姐姐", "女");
}
i = (i+1)%2;
}
}
}
//创建输出任务
class Output1 implements Runnable{
Des1 des;
public Output1(Des1 des) {
super();
this.des = des;
}
public Output1() {
super();
// TODO Auto-generated constructor stub
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
des.get();
}
}
}
//创建数据类
//封装类的原则:是你的活你做,不是你的活不要做
class Des1{
String name;
String sex;
Boolean flag = false;//创建一个标识,控制唤醒与等待的切换
//获取数据--处理输入
public synchronized void setData(String name,String sex) {
if(flag == true) {
try {//让输入线程等待,当flag的值为true的时候
//在执行代码的时候,这里对应的是那个线程,锁对象 操纵的就是哪个线程
wait();//只要一执行wait,线程就会立即停止在这里,等待下次唤醒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name;
this.sex = sex;
// if(i == 1) {
// des.name = "凤姐";
// des.sex = "男";
// }else {
// des.name = "芙蓉姐姐";
// des.sex = "女";
// }
// i = (i+1)%2;
flag = !flag;
notify();//唤醒输出线程
//当执行唤醒的时候,在线程池中没有找到被当前的所标记的线程,我们称为空唤醒,空唤醒对程序没有影响,程序允许空唤醒
}
//将数据打印到控制台-处理数据
public synchronized void get() {
if(flag == false) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Des1 [名字=" + name + ", 性别=" + sex + "]");
flag = !flag;
notify();
}
@Override
public String toString() {
return "Des1 [名字=" + name + ", 性别=" + sex + "]";
}
}
public static void main(String[] args) {
//1.创建产品
Product product= new Product();
//2.创建生产任务,消费任务
Producer producer = new Producer(product);
Consumer consumer = new Consumer(product);
//创建生产线程,消费线程
Thread t1 = new Thread(producer);
Thread t2 = new Thread(consumer);
//4.开启线程
t1.start();
t2.start();
}
}
//创建产品类
class Product{
String name;
double price;
int count;
boolean flag = false;//用来唤醒与等待之间切换
//为生产者准备数据
public synchronized void setProduce(String name,double price) {
if(flag == true) {
try {
wait();//让生产线程等待
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.name = name;
this.price = price;
System.out.println(Thread.currentThread().getName()+ " 生产了:"+name+" 产品的数量:"+count+" 产品的价格:"+price);
}
count++;
flag = !flag;
notify();//唤醒消费线程
}
//为消费者准备数据
public synchronized void consume() {
if(flag == true) {
try {
wait();//让消费线程等待
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ " 生产了"+name+" 产品的数量:"+count+" 产品的价格"+price);
}
flag = !flag;
notify();//唤醒生产线程
}
}
//创建生产任务
class Producer implements Runnable {
Product product;
public Producer() {
super();
// TODO Auto-generated constructor stub
}
public Producer(Product product) {
super();
this.product = product;
}
public void run() {
while(true) {
product.setProduce("bingbing", 10);
}
}
}
//创建消费任务
class Consumer implements Runnable {
Product product;
public Consumer() {
super();
// TODO Auto-generated constructor stub
}
public Consumer(Product product) {
super();
this.product = product;
}
public void run() {
while(true) {
product.consume();
}
}
}
public static void main(String[] args) {
//1.创建产品
Product1 product = new Product1();
//创建生产任务,消费任务
Producer1 producer1 = new Producer1(product);
Consumer1 consumer1 = new Consumer1(product);
//3.创建生产线程,消费线程
Thread t0 = new Thread(producer1);
Thread t1 = new Thread(producer1);
Thread t2 = new Thread(consumer1);
Thread t3 = new Thread(consumer1);
//开启线程
t0.start();
t1.start();
t2.start();
t3.start();
}
}
//创建产品类
class Product1{
String name;
double price;
int count;
boolean flag = false;//用来唤醒与等待之间切换
//为生产者准备数据
public synchronized void setProduce(String name,double price) {
while(flag == true) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name;
this.price = price;
count += 1;
System.out.println(Thread.currentThread().getName()+ " 生产了"+name+" 产品的数量:"+count+" 产品的价格"+price);
flag = !flag;
notifyAll();
}
//为消费者准备数据
public synchronized void consume() {
while(flag == false) {
try {
wait();//让消费线程等待
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+ " 消费了"+name+" 产品的数量:"+count+" 产品的价格"+price);
flag = !flag;
notifyAll();
}
}
//创建生产任务
class Producer1 implements Runnable {
Product1 product;
public Producer1() {
super();
// TODO Auto-generated constructor stub
}
public Producer1(Product1 product) {
super();
this.product = product;
}
public void run() {
while(true) {
product.setProduce("bingbing", 10);
}
}
}
class Consumer1 implements Runnable {
Product1 product;
public Consumer1() {
super();
// TODO Auto-generated constructor stub
}
public Consumer1(Product1 product) {
super();
this.product = product;
}
public void run() {
while(true) {
product.consume();
}
}
}
同步代码块
进行同步操作的代码
public static void main(String[] args) {
//1.创建产品
Product1 product = new Product1();
//创建生产任务,消费任务
Producer1 producer1 = new Producer1(product);
Consumer1 consumer1 = new Consumer1(product);
//3.创建生产线程,消费线程
Thread t0 = new Thread(producer1);
Thread t1 = new Thread(producer1);
Thread t2 = new Thread(consumer1);
Thread t3 = new Thread(consumer1);
//开启线程
t0.start();
t1.start();
t2.start();
t3.start();
}
}
//创建产品类
class Product2{
String name;
double price;
int count;
//创建Lock的对象
Lock lock = new ReentrantLock();
boolean flag = false;//用来唤醒与等待之间切换
//创建用于生产者线程的Condition对象
Condition conditionProducer = lock.newCondition();
//创建用于消费者线程的Condition对象
Condition conditionConsumer = lock.newCondition();
//为生产者准备数据
public void setProduce(String name,double price) {
try {
lock.lock();
while(flag == true) {
try {
conditionProducer.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name;
this.price = price;
count += 1;
System.out.println(Thread.currentThread().getName()+ " 生产了"+name+" 产品的数量:"+count+" 产品的价格"+price);
flag = !flag;
conditionConsumer.signal();
} finally {//必须执行的代码
// TODO: handle finally clause
lock.unlock();
}
}
//为消费者准备数据
public void consume() {
try {
lock.lock();
while(flag == false) {
try {
conditionConsumer.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+ " 消费了"+name+" 产品的数量:"+count+" 产品的价格"+price);
flag = !flag;
conditionProducer.signal();
} finally {
// TODO: handle finally clause
lock.unlock();
}
}
}
//创建生产任务
class Producer2 implements Runnable {
Product2 product;
public Producer2() {
super();
// TODO Auto-generated constructor stub
}
public Producer2(Product2 product) {
super();
this.product = product;
}
public void run() {
while(true) {
product.setProduce("bingbing", 80);
}
}
}
//创建消费任务
class Consumer2 implements Runnable {
Product2 product;
public Consumer2() {
super();
// TODO Auto-generated constructor stub
}
public Consumer2(Product2 product) {
super();
this.product = product;
}
public void run() {
while(true) {
product.consume();
}
}
}
public static void main(String[] args) {
Test test = new Test();
Thread thread = new Thread(test);
/*
* 当程序调用setDaemon的时候,并且将参数设置成true,他就变成了守护线程
* 注意:这个方法一定要在start方法之前调用
*/
thread.setDaemon(true);
thread.start();
int i = 0;
while (true) {
if(i++ == 10) {
System.out.println(Thread.currentThread().getName()+"i:"+i);
break;//主线程结束
}
}
}
}
class Test implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
System.out.println("守护线程");
}
}
}
public static void main(String[] args) {
Dog dog = new Dog();
Thread thread0 = new Thread(dog);
Thread thread1 = new Thread(dog);
thread1.start();
thread0.start();
/*
* 当线程开始工作后,让thread0调用join()方法,他的优先级会高于main线程
* 注意:join方法必须在线程开始后调用
*/
try {
thread0.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i = 0; i < 10;i++) {
System.out.println(Thread.currentThread().getName()+" i:"+i);
}
}
}
class Dog implements Runnable{
public void run() {
for(int i = 0; i < 10;i++) {
System.out.println(Thread.currentThread().getName()+" i:"+i);
}
}
}