线程通信的问题
/*例如: A B C
* A--1 B--6 C--11
* A--2 B--7 C--12
* A--3 B--8 C--13
* A--4 B--9 C--14
* A--5 B--10 C--15
* 在回来重新跑
* wait();执行该方法,当前线程就会进入线程阻塞,换成其他线程 ,并释放同步监视器
* notify();执行该方法,就会唤醒被wait阻塞的一个线程
* 如果有多个线程wait阻塞了,优先唤醒优先级高的
* notifyAll();唤醒所有被wait阻塞的线程
* 说明:都定义在Object类中
* 上述三个方法都必须在同步代码块或者同步方法中使用
* 上述三个方法调用者都必须是同步代码块或者同步监视器
*
* sleep和wait有什么异同
* 相同点:都可以是当前线程进入阻塞状态
* 不同点:
*
* 1. sleep()属于Thread wait()属于Object
* 2. 调用者要求不同,sleep在任何位置都可以使用,wait()只能在同步代码块或者同步方法中使用
* 3. 释放同步监视器:如果两个方法都在同步代码块中调用,
* sleep(),不会释放同步资源
* wait().会释放资源
*
*/
上代码:
public class ThreadDemo01 {
public static void main(String[] args) {
Num n=new Num();
Thread a=new Thread(n,"A");
Thread b=new Thread(n,"B");
Thread c=new Thread(n,"C");
a.start();
b.start();
c.start();
}
}
//公用的数
class Num implements Runnable{
int n=0;//计数器
//每加五次就换一个线程
@Override
public void run() {
while(true){
show();
}
}
public synchronized void show(){
// notify();
//每次执行累加
n++;
System.out.println(Thread.currentThread().getName()+"----"+n);
//n%5==0的时候,就表示当前线程走了5次,需要让当前的线程阻塞,换成其他线程
if(n%5==0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
生产消费者问题:
/**
* @author DeYou
* @date 2022/4/1 21:39
*
* 生产者消费者模型
* 生产者生产好的产品交给店员,消费者从店员手中买走产品
* 假设店员一次只能持有固定数量的产品(20),如果生产者试图产生更多的产品,
* 店员就会叫生产者停一下,如果由消费者从店员手中买走产品,此时店员手中就有空位置了,生产者就可以继续生产
* 如果店员手中没有产品,店员就会告诉消费者你等一下,等店员手中有了产品再通知消费者来领取产品
*
* 分析:
* 1.存不存在多线程问题? 存在,生产者线程;消费之线程
* 2.是否有数据共享问题? 是,产品的数量,店员
* 3.存不存在过程安全问题? 存在,上保安(上锁)
*/
上代码:
public class ThreadDemo02 {
public static void main(String[] args) {
Clerk dd=new Clerk();//店员
//生产者
Product sy=new Product(dd);
sy.setName("十堰");
Product zy=new Product(dd);
zy.setName("烛影");
//消费者
Consumer ck=new Consumer(dd);
ck.setName("苍空");
Consumer tr=new Consumer(dd);
tr.setName("天日");
Consumer ft=new Consumer(dd);
ft.setName("浮屠");
Consumer hy=new Consumer(dd);
hy.setName("黑炎");
//启动
sy.start();
zy.start();
ck.start();
tr.start();
ft.start();
hy.start();
}
}
//店员
class Clerk{
//产品数量
int productCount=0;
//店员可以要求生产者生产产品
public synchronized void produceProduct(){
if(productCount<20){
notifyAll();//数量小于20的时候,才可以调用生产产品的线程
productCount++;
System.out.println(Thread.currentThread().getName()+":开始生产"+productCount+"产品");;
}else{//如果产品数量大于等于20.让产品生产者等待一下
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//店员的消费产品的方法
public synchronized void consumeProduct(){
//如果产品数量大于0才可以消费
if (productCount>0){
notifyAll();//唤醒
System.out.println(Thread.currentThread().getName()+":开始消费第"+productCount+"个产品");
productCount--;
}else{
//产品小于等于0,告诉消费者等一下
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//生产者线程
class Product extends Thread{
Clerk clerk;
public Product(Clerk clerk){
this.clerk=clerk;
}
@Override
public void run(){
System.out.println(getName()+"厂家开始生产产品------");
while(true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.produceProduct();//店员开始让生产者生产
}
}
}
class Consumer extends Thread{
Clerk clerk;
public Consumer(Clerk clerk){
this.clerk=clerk;
}
@Override
public void run(){
System.out.println(getName()+"消费者:正在消费产品.......");
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.consumeProduct();//店员服务消费者消费
}
}
}
多线程的实现
/**
* @author DeYou
* @date 2022/4/2 18:32
* java实现
* 多线程方法一:
* 继承Thread
* 多线程方法二:
* 实现Runnable接口
* 多线程方法三:
* 实现Callable接口
* 多线程方法四:
* 线程池的方式
*
*
* 实现Callable方式河Runnable方式的优势
* 1.Call可以有返回值
* 2.Call可以抛出异常,被外面的调用者捕获异常,从而获取更多的异常信息
* 3.Callable支持泛型
*/
上代码:
public class ThreadDemo03 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//3.创建Callable实例对象
CallableTest c=new CallableTest();
//创建futureTask对象,将上述的CallableTest实例传入构造中
FutureTask ft=new FutureTask(c);
//5.创建Thread对象,将上述FutureTask实例传入构造中
Thread t=new Thread(ft);
//6.启动线程
t.start();
/*
在call方法返回值是通过FutureTask对象调用get方法获取的
*/
System.out.println("call方法的返回值是:"+ft.get());
}
}
//创建一个类实现Callable接口
class CallableTest implements Callable{
//重写call()
@Override
public Object call() throws Exception {
int sum=0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
return sum;
}
}
希望在此你能有不少的收获,如果有错的话,请斧正!