线程之间通信的方法

线程之间通信的方法有四种:

1. 共享内存的方法

该方法有两种实现形式:
 synchronized和volatile

使用synchronized,多线程环境下会造成阻塞,如果有多个线程同时要对内存中的一个数据进行操作,那么他们都把内存中的值读到自己的工作内存中。使用synchronized修饰的haul同一时间只能有一个线程进行操作,对数据更新完之后重新刷新会主存,自动释放锁,然后下一个线程来读取内存中的值,实现线程通信

使用volatile:用它修饰的变量线程在对其进行操作时,数据更新完之后直接刷新会主存,其他线程读的话,即使通过内存有数据,也不读,读的是主内存中的值,从而实现通信

2.synchronized+wait+notify(同步,等待,唤醒)

在生产者消费者模式中,生产者生产到库存满了以后就不能再生产,调用wait方法挂起,然后在调用notify方法唤醒消费者进行消费,可以实现线程之间的通信

举例:

**
 * 资源类,表示生产者和消费者操作的资源
 */
public class Resource {
   private int num=0;
   private int size=10;
   public synchronized void put()
   {
       while (num>=size)
       {
           System.out.println("生产者进入等待...");
           try {
               this.wait();
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
       num++;
       System.out.println("当前线程是:"+Thread.currentThread().getName()+"资源数量:"+num);
       notifyAll();
   }
   public synchronized void remove()
   {
       while (num<=0)
       {
           System.out.println("消费者进入等待");
           try {
               this.wait();
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
       num--;
       System.out.println("当前线程:"+Thread.currentThread().getName()+"资源数量"+num);
       notifyAll();
   }


}
public class Productor implements Runnable{
    private Resource resource;

    public Productor(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        for (int i = 0; i <20 ; i++) {
            resource.remove();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Consumer implements Runnable  {
    private Resource resource;

    public Consumer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        for (int i = 0; i <20 ; i++) {
            resource.put();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Test {
    public static void main(String[] args) {
    Resource resource=new Resource();
    Consumer consumer=new Consumer(resource);
    Productor productor=new Productor(resource);
    new Thread(consumer).start();
    new Thread(productor).start();

    }
}

3.Lock+condition+await+singal 实现

一般情况下使用ReentrantLock

举例:

public class Resource {
    private int num=0;
    private int size=10;
    private ReentrantLock lock=new ReentrantLock();
    private Condition condition=lock.newCondition();
    public  void put()
    {
        lock.lock();
        while (num>=size)
        {
            try {
                System.out.println("生产者进入等待状态...");
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        num++;
        System.out.println("当前线程是:"+Thread.currentThread().getName()+"当前资源数量:"+num);
        condition.signal();
        lock.unlock();
    }
    public void remove()
    {
        lock.lock();
        while(num<=0)
        {
            try {
                System.out.println("消费者进入等待状态...");
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        num--;
        System.out.println("当前线程是:"+Thread.currentThread().getName()+"资源数量:"+num);
        condition.signal();
        lock.unlock();

    }


}
public class Productor implements Runnable{
    private Resource resource;

    public Productor(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        for (int i = 0; i <20 ; i++) {
            resource.remove();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Consumer implements Runnable  {
    private Resource resource;

    public Consumer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        for (int i = 0; i <20 ; i++) {
            resource.put();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

public class Test {
    public static void main(String[] args) {
        Resource resources = new Resource();
        Consumer consumer = new Consumer(resources);
        Productor productor=new Productor(resources);
        System.out.println();
        new Thread(consumer).start();
        new Thread(productor).start();

    }

}

4.管道间通信

在两个线程之间建立一个通道,就是pipeInputStream和pipeOutputStream,inputstream用户接受信息,outputstream用户发送信息。

举例如下:
 

public class ReadData {
    public void readMethod(PipedInputStream input) {
        System.out.println("read");
        byte[] byteArray = new byte[20];
        try {
            int readLength = input.read(byteArray);
            while (readLength != -1) {
                String newData = new String(byteArray, 0, readLength);
                System.out.println(newData);
                readLength = input.read(byteArray);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 

public class WriteData {
    public void writeMethod(PipedOutputStream out) {
        System.out.println("write:");
        try {
            for (int i = 0; i < 300; i++) {
                String outData = "" + (i + 1);
                out.write(outData.getBytes());
                System.out.println(outData);
            }
            System.out.println();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();

        }
    }
}

 

public class ThreadRead extends Thread{
    private ReadData readData;
    private PipedInputStream inputStream;

    public ThreadRead(ReadData readData,PipedInputStream inputStream) {
        this.readData = readData;
        this.inputStream=inputStream;
    }
    @Override
    public void run()
    {
        readData.readMethod(inputStream);
    }

}
public class ThreadWrite extends Thread {
    private WriteData writeData;
    private PipedOutputStream out;

    public ThreadWrite(WriteData writeData, PipedOutputStream out) {
        this.writeData = writeData;
        this.out = out;
    }
    @Override
    public void run()
    {
        writeData.writeMethod(out);
    }

}

 

public class Test {
    public static void main(String[] args) {
        try {
            WriteData writeData = new WriteData();
            ReadData readData = new ReadData();
            PipedInputStream inputStream = new PipedInputStream();
            PipedOutputStream outputStream = new PipedOutputStream();
            outputStream.connect(inputStream);
            ThreadRead threadRead=new ThreadRead(readData,inputStream);
            threadRead.start();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ThreadWrite threadWrite=new ThreadWrite(writeData,outputStream);
            threadWrite.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

以上是关于线程之间通信的方法,希望对你有用

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值