1.线程通信
/*
线程间通信:
多个线程,运行任务不一样,处理资源一样。
*/
//资源
class Resource
{
String name;
String sex;
}
//输入
class Input implements Runnable
{
Resource r;
// Object obj = new Object();//同步步骤一
Input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)//同步步骤二
{
if(x ==0)
{
r.name = "mk";
r.sex = "n";
}
else
{
r.name = "ll";
r.sex = "nv";
}
}
}
x = (x+1)%2;
}
}
//输出
class Output implements Runnable
{
Resource r;
// Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
r.name = "ll";
r.sex = "n";
System.out.println(r.sex);
}
}
}
}
class ResourceDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output o = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(o);
t1.start();
t2.start();
}
}
2.等待唤醒机制
/*
线程间通信:
多个线程,运行任务不一样,处理资源一样。
等待唤醒机制:
涉及的方法:
1.wait(): 让线程处于冻结状态,被wait的线程会被存储到线程池中。
2.notify():唤醒线程池中的任意一个线程
3.notifyall(): 唤醒线程池中的所有线程。
这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法。必须要明确到底操作的是
那个锁上的线程。
为什么操作线程的方法 wait notify botifyall 定义在object中:
因为这些方法是监视器的方法,监视器其实就是锁。
锁可以是任意的对象,任意的对象调用的方法一定定义在object中。
*/
//资源
class Resource
{
String name;
String sex;
Boolean flag;
}
//输入
class Input implements Runnable
{
Resource r;
// Object obj = new Object();//同步步骤一
Input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)//同步步骤二
{
if(r.flag)
r.wait();
if(x ==0)
{
r.name = "mk";
r.sex = "n";
}
else
{
r.name = "ll";
r.sex = "nv";
}
}
r.flag = true;
r.notify();
}
x = (x+1)%2;
}
}
//输出
class Output implements Runnable
{
Resource r;
// Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
if(!r.flag)
r.wait();
System.out.println(r.sex);
r.flag = false;
r.notify();
}
}
}
}
class ResourceDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output o = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(o);
t1.start();
t2.start();
}
}
3.生产一只卖一只
/*
线程间通信:
多个线程,运行任务不一样,处理资源一样。
等待唤醒机制:
题目: 生产者 消费者
*/
//资源
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String name)
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println("生产者"+this.name);
flag = true;
notify();
}
public synchronized void out()
{
if(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(this.name+"消费者");
flag = false;
notify();
}
}
class Prod implements Runnable
{
private Resource r;
Prod(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.set("ya");
}
}
class Cos implements Runnable
{
private Resource r;
Cos(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class demo
{
public static void main(String[] args)
{
Resource r = new Resource();
Prod p =new Prod(r);
Cos c = new Cos(r);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
4.多生产多消费
/*
线程间通信:
多个线程,运行任务不一样,处理资源一样。
等待唤醒机制:
题目: 生产者 消费者
2.多生产者,多消费者
if 判断标记,只有一次,会导致不该运行的线程运行了,出现数据错误的情况
while 判断标记,解决了现场获取执行权后,是否要运行!
notifyAll 解决了本方线程一定会唤醒对方线程,
notify 只能唤醒一个线程,如果本方唤醒本方,没有意义,而且while+notify 会导致死锁
*/
//资源
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String name)
{
while(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println("生产者"+this.name);
flag = true;
notifyAll();
}
public synchronized void out()
{
while(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(this.name+"消费者");
flag = false;
notifyAll();
}
}
class Prod implements Runnable
{
private Resource r;
Prod(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.set("ya");
}
}
class Cos implements Runnable
{
private Resource r;
Cos(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class demo
{
public static void main(String[] args)
{
Resource r = new Resource();
Prod p =new Prod(r);
Cos c = new Cos(r);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
Thread t3 = new Thread(p);
Thread t4 = new Thread();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
5.lock 接口
jdk1.5以后将同步和锁风闸U那个成了对象,并将操作锁的隐式方式定义到了该对象中,将隐式动作变成了显示动作。
/*
线程间通信:
多个线程,运行任务不一样,处理资源一样。
等待唤醒机制:
题目: 生产者 消费者
2.多生产者,多消费者
*/
//资源
import java.util.concurrent.locks.*;
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
Lock lock = new ReentrantLock();//创建一个锁对象
Condition con = lock.newCondition();//通过已有的锁获得该锁上的监视器对象
public void set(String name)
{
lock.lock();
try
{
while(flag)
try{con.await();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println("生产者"+this.name);
flag = true;
con.signalAll();
}
finally
{
lock.unlock();
}
}
public synchronized void out()
{
lock.lock();
try
{
while(!flag)
try{con.await();}catch(InterruptedException e){}
System.out.println(this.name+"消费者");
flag = false;
con.signalAll();
}
finally
{
lock.unlock();
}
}
}
class Prod implements Runnable
{
private Resource r;
Prod(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.set("ya");
}
}
class Cos implements Runnable
{
private Resource r;
Cos(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class demo
{
public static void main(String[] args)
{
Resource r = new Resource();
Prod p =new Prod(r);
Cos c = new Cos(r);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
Thread t3 = new Thread(p);
Thread t4 = new Thread();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
二:
/*
线程间通信:
多个线程,运行任务不一样,处理资源一样。
等待唤醒机制:
题目: 生产者 消费者
2.多生产者,多消费者
*/
//资源
import java.util.concurrent.locks.*;
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
Lock lock = new ReentrantLock();//创建一个锁对象
// Condition con = lock.newCondition();//通过已有的锁获得该锁上的监视器对象
//通过已有的锁获取两组监视器,一组见识生产者,一组监视消费者
Condition con1 = lock.newCondition();//生产者
Condition con2 = lock.newCondition();//消费者
public void set(String name)
{
lock.lock();
try
{
while(flag)
try{con1.await();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println("生产者"+this.name);
flag = true;
con2.signal();
}
finally
{
lock.unlock();
}
}
public synchronized void out()
{
lock.lock();
try
{
while(!flag)
try{con2.await();}catch(InterruptedException e){}
System.out.println(this.name+"消费者");
flag = false;
con1.signal();
}
finally
{
lock.unlock();
}
}
}
class Prod implements Runnable
{
private Resource r;
Prod(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.set("ya");
}
}
class Cos implements Runnable
{
private Resource r;
Cos(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class demo
{
public static void main(String[] args)
{
Resource r = new Resource();
Prod p =new Prod(r);
Cos c = new Cos(r);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
Thread t3 = new Thread(p);
Thread t4 = new Thread();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
lock接口:出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成显式锁操作,同时更为灵活,可以一个锁上加多个监视器。
lock() 获取锁
unlock() 释放锁,通常需要定义在finally 代码块中
Condition接口: 出现代替了object 中的wait,notify ,notifyall 方法。
将这些监视器方法单独进行了封装,变成condition监视器对象,可以任意锁进行组合。
await()
signal()
signalall()
/*
wait() 和sleep() d的区别
1.wait 可以指定时间,也可以不指定,sleep必须指定
2.在同步中时对于cpu的执行权和锁的处理不一样
wait() 释放执行权,释放锁
sleep() 释放执行权,不释放锁
*/
6.停止线程
线程停止方法:
1.stop 方法
2.run 方法结束
怎么控制线程的任务结束呢?
任务中都有循环结构,只要控制循环就能结束任务,控制循环就用标记。 十四课!