zoukankan      html  css  js  c++  java
  • Java多线程之间的通信

    目录: 

    1 synchronized的作用域

    2 线程的状态及线程类的一些常用方法:

    3 一个简单多线程通信的例子: 

    1 synchronized的作用域:

    假设存在如下条件:2个线程(ThreadOne and ThreadTwo),1个类(TestObject), 3个TestObject的实例(object, object1 and object2).

     构造函数如下:

    ThreadOne threadOne = new ThreadOne(object1) 

    ThreadTwo threadTwo = new ThreadTwo(object2)  

    TestObject testObject = new TestObject ("object")

    TestObject.java

    String getName();

    void setName();

    现在我们分作用域为:实例内,整个对象,代码块,子类

    实例内:只有一个实例的情况下(设ThreadOne和ThreadTwo都是通过object来构造的,TestObject的2个方法均由synchronized修饰) ,当ThreadOne在调用getName()的时候,ThreadTwo是没有权利调用object这个实例的所有用synchronized方法。即对这个实例object上锁了。只有等到ThreadOne执行完getName()方法的时候ThreadTwo才可以调用setName()方法;

    整个对象:如果存在2个实例object1和object2,并且分别用来构造ThreadOne和ThreadTwo。那么ThreadOne和ThreadTwo调用TestObject内的所有synchronized方法是相互独立不受影响的。但是如果用synchronized static来修饰方法情况就不一样了,这样是整个TestObject对象被上锁了,只要它的一个实例调用了synchronized static方法,其他所有的实例都不能调用任何synchronized static方法;

    代码块:除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;

    子类: synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;

    2 线程的状态以及线程的常用方法:

    线程的状态有就绪状态,运行状态,等待状态,休眠状态,终止状态,当条件齐备的时候就绪状态的线程就会开始执行。

    wait()/notify()/notifyAll(): wait()之后线程释放锁进入等待状态,就绪状态的线程才可以利用锁;进入等待状态的线程只有通过notify()/notifyAll()才能够被唤醒(当条件发生变化)。和synchronized连用。

    sleep(): 不释放琐,只是作一段时间的休眠,休眠完后继续执行。

    yield(): 释放锁,使当前线程马上回到就绪状态,也可能马上在执行。 

    3 一个简单多线程通信的例子:

     ---------------------------------------------------

    package com.kelin1314;

    public class TestObject {

    private String name;

    private boolean flag = true;

    public TestObject(String name) {

    this.name = name;

    }

    public synchronized String getName() {

    try {

    System.out.println("begin get");

    while (!flag) {

    wait();

    }

    flag = true ? (flag = false) : (flag = true);

    System.out.println("over get");

    notify();

    } catch (Exception e) {

    e.printStackTrace();

    }

    return name;

    }

    // public synchronized static void setName(String name) {

    public synchronized void setName(String name) {

    try {

    System.out.println("begin set");

    while (flag) {

    wait();

    }

    flag = true ? (flag = false) : (flag = true);

    System.out.println("over set");

    notify();

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    ---------------------------------------------------

    package com.kelin1314;


    /**

     * This thread is used to test the variable scope of key word "synchronized".

     * 

     * @author Administrator

     * 

     */

    public class TestThreadOne extends Thread {

    private TestObject object;

    public TestThreadOne(TestObject object) {

    this.object = object;

    }

    @Override

    public void run() {

    while (true) {

    object.getName();

    }

    }

    }

    --------------------------------------------------

    package com.kelin1314;

    public class TestThreadTwo extends Thread{

    private TestObject object;

    public TestThreadTwo(TestObject object){

    this.object = object;

    }

    @Override

    public void run() {

    while(true){

    object.setName("two");

    }

    }

    }

    ---------------------------------------------

    package com.kelin1314;

    public class Main {

    /**

    * @param args

    */

    public static void main(String[] args) {

    TestObject object = new TestObject("object");

    TestThreadOne testThreadOne = new TestThreadOne(object);

    TestThreadTwo testThreadTwo = new TestThreadTwo(object);

    testThreadOne.start();

    testThreadTwo.start();

    }

    }

    ---------------------------------------------------- 


  • 相关阅读:
    神经网络训练收敛的解决办法
    minSdkVersion
    onlyoffice使用
    linux系统磁盘不足处理方法
    编辑docker容器中的文件
    如何使用Java获取上传图片需要旋转的角度且获取正确方向的图片
    Java数据类型转换
    bat脚本实现jdk安装、环境变量添加及jar包运行
    java实现文件上传接口及java调用文件上传接口
    flutter常用问题查询
  • 原文地址:https://www.cnblogs.com/kelin1314/p/1789324.html
Copyright © 2011-2022 走看看