资讯专栏INFORMATION COLUMN

java-实战java高并发程序设计-ch2java并行程序基础

yy13818512006 / 272人阅读

摘要:所以需要等来确保程序中隐蔽的错误没有提示的错误比如两个正数相加,溢出导致其值为负数。并发下的两个线程同时对一个对象,每个线程个对象,最终结果可能中有万个对象。可能对象个数少于万可能内部结构发生破坏,程序无法终止,会被大量消耗。

java并行程序基础

参考:
https://github.com/chengbingh...

2.1 有关线程, 需要知道的事

进程是线程的容器
线程状态图:


2.2 线程的基本操作
2.2.1新建线程
2.2.2终止线程
stop 暴力终止线程,废弃方法


2.2.3线程中断
方法:

2.2.4 等待(wait)和唤醒notify
注意:
wait 是object的一个方法,调用wait方法的对象,必须在synchronized 中,因为要获取它的监视器。
wait会释放锁

public class SimpleWN {

    final static Object obj = new Object();
    
    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(obj) {
                    System.out.println("t1.start,and t1 will wait");
                    try {
                        // 调用wait 方法的这个对象必须被synchronizeed
                        //wait 会释放锁
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t1 was notify");


                }

            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(obj){
                    System.out.println("t2 start and will notify t1");
                    // 调用notify 方法的这个对象必须被synchronizeed
                    //如果 有n个线程此时都是由于调用了obj.wait方法,那么会唤醒任意一个
                    obj.notify();
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println("t2 end run");
                }
            }
        });
        t1.start();
        t2.start();
    }
}
输出:注意锁
t1.start,and t1 will wait
t2 start and will notify t1
t2 end run
t1 was notify

2.2.5 挂起(suspend)和继续执行(resume)
suspend()和resume方法

2.2.6 join 和yeild
join:加入,把线程当做一个方法了。
yeild:让出线程执行权,但是还是会争夺线程的执行权

2.3 volatile 与java 内存模型(JMM)

JMM: 原子性,可见性,有序性
原子性:32位虚拟机中多线程读写long不会有问题,但是不能保证i++

可见性:
虚拟机在-server模式下会进行优化,下面的程序永远不会跳出。

/**
 * @author ChengBing Han
 * @date 9:39  2018/6/22
 * @description
 */
public class NoVisibility {
    private static boolean ready;
    private static int number;


    private static class ReaderThread extends Thread {
        public void run() {

            /*
           while (!ready){
                System.out.println(new Date());
            }*/
            //这个和上述的优化不同,这个在-server模式下会优化
            while (!ready) ;
            System.out.println(number);
        }

    }

    public static void main(String[] args) throws InterruptedException {
        
        //永远不会终止程序
        new ReaderThread().start();
        Thread.sleep(1000);
        number = 42;
        ready = true;
        Thread.sleep(2000);
    }
}

备注:上述ready 用volatile 修饰后就会退出,或者用-client 模式启动虚拟机

2.4 分门别类的管理 线程组 2.5 驻守线程的后台:守护线程 2.6 线程优先级:先干重要的事

1-10,优先级逐渐升高

2.7 synchronized(内部锁)
volatile 可以保证原子性,和可见性,但是如果两个线程同时修改了某个变量,那么还是无法识别的,这时volatile的局限性。所以需要synchronized等来确保

2.8 程序中隐蔽的错误

2.8.1 没有提示的错误e
比如两个正数int 相加, 溢出导致 其值为负数。

2.8.2 并发下的ArrayList
两个线程同时对一个ArrayList add 对象,每个线程add 10000 个对象, 最终结果
可能1:ArrayList 中有2万个对象。
可能2:抛出异常
ArrayList 内部结构被破坏了

可能3:ArrayList 中的对象个数小于2万

2.8.3 并发下的HashMap
两个线程同时对HashMap添加对象,每个线程add 10000 个对象,最终结果
可能1:HashMap 中有2万个对象。
可能2:对象个数少于2万
可能3:HashMap内部结构发生破坏,程序无法终止,cpu会被大量消耗。
2.8.4 错误加锁

static Integer i = 0;
.........
synchronized(i){
   i++;
}
//问题在于, integer是不可变的,所以每次i++都会创建一个新的对象。可以用javap 反编译查看

允许多个线程同时访问:信号量

允许几个线程访问

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71270.html

相关文章

  • java-实战java并发程序设计-ch1走入并行的世界

    摘要:参考何去何从的并行计算忘记该死的并行并行程序的复杂性和乱序性,并行程序设计十分复杂。可怕的现实摩尔定律的失效单核上的晶体管数目达到极限。并发级别阻塞重入锁无饥饿两个线程优先级不同,低优先级的可能产生饥饿。 Chapter1 参考:https://github.com/chengbingh... 1.1何去何从的并行计算 1.1.1 忘记该死的并行并行程序的复杂性和乱序性,并行程序设计十...

    suxier 评论0 收藏0
  • 实战java并发程序设计第一章

    摘要:通过指令重排可以减少流水线停顿提升巨大效率原则程序顺序原则一个线程内保证语义的串行性。锁规则解锁必然发生在随后的加锁前。线程的方法先于它的每一个动作。 1. 基本概念 同步(Synchronous)和异步(Asynchronous) 并发(Conncurrency)和并行(Parallelism) 临界区 阻塞(Blocking)与非阻塞(Non-Blocking) 死锁(Deadl...

    moven_j 评论0 收藏0
  • 如何提Java并行程序性能

    摘要:因此将变量存放于独立的缓存行中,也有助于变量在多线程访问是的性能提升实战高并发程序设计,大量的高并发库都会采用这种技术。 在Java程序中,多线程几乎已经无处不在。与单线程相比,多线程程序的设计和实现略微困难,但通过多线程,我们却可以获得多核CPU带来的性能飞跃,从这个角度说,多线程是一种值得尝试的技术。那么如何写出高效的多线程程序呢? 有关多线程的误区:线程越多,性能越好 不少初学者...

    everfight 评论0 收藏0
  • 后端好书阅读与推荐(续三)

    摘要:后端好书阅读与推荐系列文章后端好书阅读与推荐后端好书阅读与推荐续后端好书阅读与推荐续二后端好书阅读与推荐续三这里依然记录一下每本书的亮点与自己读书心得和体会,分享并求拍砖。然后又请求封锁,当释放了上的封锁之后,系统又批准了的请求一直等待。 后端好书阅读与推荐系列文章:后端好书阅读与推荐后端好书阅读与推荐(续)后端好书阅读与推荐(续二)后端好书阅读与推荐(续三) 这里依然记录一下每本书的...

    lauren_liuling 评论0 收藏0
  • 后端好书阅读与推荐(续三)

    摘要:后端好书阅读与推荐系列文章后端好书阅读与推荐后端好书阅读与推荐续后端好书阅读与推荐续二后端好书阅读与推荐续三这里依然记录一下每本书的亮点与自己读书心得和体会,分享并求拍砖。然后又请求封锁,当释放了上的封锁之后,系统又批准了的请求一直等待。 后端好书阅读与推荐系列文章:后端好书阅读与推荐后端好书阅读与推荐(续)后端好书阅读与推荐(续二)后端好书阅读与推荐(续三) 这里依然记录一下每本书的...

    ckllj 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<