• (转载)java线程


    今天重新把昨晚的线程同步面试题做一遍时,发现实际情况运行下来时,线程一直不同步。后来经过不断测试,发现自己的一个误区。

    之前一直以为,线程如果被唤醒后再次执行时,会从头开始运行这个线程,也就是重新运行Runnable中的run()方法;

    而实际情况是,被唤醒并且被执行的线程是从上次阻塞的位置从下开始运行,也就是从wait()方法后开始执行。

    所以判断是否进入某一线程的条件 是用while判断,而不是用If判断判断。

    下面举例说明:

    如果三个线程同步工作,第一个线程打印1,2,3,4,5   ,然后第二个线程打印1,2,3,4,5  ,接着第三个线程也打印 1,2,3,4,5,重复100次。

    public class Thread_test {

    static final manage m = new manage();

    public static void main(String[] args) {
    //线程一
    new Thread(new Runnable() {
    @Override
    public void run() {
    // TODO Auto-generated method stub
    for(int i=0;i<50;i++){
    m.threadPrint(i,0);
    }
    }
    }).start();

    //线程二
    new Thread(new Runnable(){

    public void run(){
    for(int i=0;i<50;i++){
    m.threadPrint(i,1);
    }
    }
    }).start();

    //线程三
    new Thread(new Runnable(){

    public void run(){
    for(int i=0;i<50;i++){
    m.threadPrint(i,2);
    }
    }
    }).start();

    }

    }


    //控制线程执行的顺序
    class manage{
    //权限,0代表1号线程执行,1代表二号线程执行,2代表三号线程执行
    private int isA = 0;

    public synchronized void threadPrint(int i,int n){
    /*该处应用while来判断是否轮到该线程执行,假如用If判断的话,如果该线程阻塞后再次被唤醒执行时(其他线程调用this.notifyAll()),
    他会从this.wait()后面的代码开始执行,即时没轮到该线程执行*/
    while(this.isA != n){
    try {
    this.wait();
    } catch (Exception e) {
    // TODO: handle exception
    }
    }
    for(int j=0;j<5;j++){
    System.out.println(Thread.currentThread().getName()+":"+(j+1)+" loop in "+(i+1));
    }
    this.isA = (this.isA+1)%3;//将权限传递给后一个进程62 this.notifyAll();
    }

    }

  • 相关阅读:
    idea添加junit4(单元测试)
    hadoop学习之路(2)
    hadoop学习之路(1)
    MySQL主从配置(两台Linux之间)
    ZooKeeper概念详解,最全整理
    Linux小知识点
    Java Freemarker 实现导出 Word文档
    Oracle学习笔记十六:常用函数
    Oracle学习笔记十五:基本数据类型
    Oracle学习笔记十四:备份与恢复案例
  • 原文地址:https://www.cnblogs.com/ggds/p/8602016.html
Copyright © 2020-2023  润新知