精华内容
下载资源
问答
  • 多线程笔记

    2017-12-28 13:29:42
    多线程笔记,包含线程创建,线程开启,线程命名,线程同步
  • 马士兵多线程笔记

    2020-06-07 20:26:15
  • java多线程笔记–lock多线程计数 文章目录java多线程笔记--lock多线程计数1.lock多线程计数 lock:主要有可重入锁,读写锁,文件锁 1.lock多线程计数 package com.ctg.test.lock; import java.util.concurrent....

    java多线程笔记–lock多线程计数


    lock:主要有可重入锁,读写锁,文件锁

    1.lock多线程计数

    package com.ctg.test.lock;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @Description: Lock解决多线程访问相同的资源
     * lock的特性:
     * 1)相比于 synchronized隐式获取、释放锁,lock需要显示的获取释放锁
     * 2)相比于 synchronized,lock可以可中断的获取锁及超时获取锁,
     * 3)ReentrantLock,同一个线程调用lock方法,可以连续多次获取锁而不被阻塞
     * @Author: 
     * @Date: 2019/5/12 0:05
     */
    public class TestLockCount {
        private  static  int num =0;
        private  static ReentrantLock lock = new ReentrantLock();
        public static void main(String[] args)throws InterruptedException {
            for(int k=0;k<100;k++){
                CountDownLatch countDownLatch = new CountDownLatch(3);
                num=0;
                Thread t1 =new Thread(new CountRunnable(countDownLatch));
                Thread t2 =new Thread(new CountRunnable(countDownLatch));
                Thread t3 =new Thread(new CountRunnable(countDownLatch));
                t1.start();
                t2.start();
                t3.start();
                countDownLatch.await();
                System.out.println("第"+(k+1)+"次计算结果,num=" + num);
            }
        }
    
        public static  class CountRunnable implements Runnable{
            private CountDownLatch countDownLatch;
            CountRunnable (CountDownLatch countDownLatch){
                this.countDownLatch=countDownLatch;
            }
            @Override
            public void run() {
                lock.lock();
                try{
                    for (int i=0;i<10000;i++){
                        num=num+1;
                        // System.out.println(Thread.currentThread().getName()+":"+num);
                    }
                }
                finally {
                    lock.unlock();
                }
                countDownLatch.countDown();
            }
        }
    }
    
    

    执行100次结果:
    在这里插入图片描述

    展开全文
  • Java 多线程笔记(1)——线程简介 Java 多线程笔记(2)——创建/启动线程 Java 多线程笔记(3)——线程的生命周期 Java 多线程笔记(4)——控制线程 Java 多线程笔记(5)——线程同步 Java 多线程笔记(6)——...

    Java菜鸟,初学多线程,使用的教材是《疯狂java讲义(第四版)》。有理解不到位的地方,欢迎批评指正~
    (文章末尾有整个笔记的pdf版本和md版本)


    Java 多线程笔记(1)——线程简介
    Java 多线程笔记(2)——创建/启动线程
    Java 多线程笔记(3)——线程的生命周期
    Java 多线程笔记(4)——控制线程
    Java 多线程笔记(5)——线程同步
    Java 多线程笔记(6)——线程通信



    6. 线程通信

    保证线程协调运行的机制。使线程间可以互相发送信号,也可以使线程等待其他线程的信号。


    6.1 传统线程通信

    Java中,使用Object类的wait()、notify()和notifyAll()三个方法实现线程通信。这三个方法必须由同步监视器调用(针对同步代码块和同步方法)。

    • 同步方法中,同步监视器是this,所以可以在同步方法中直接调用这三个方法
    • 同步代码块中,同步监视器是括号里的对象,所以要用该对象调用这三个方法

    三个方法的功能解释:

    • wait():使当前线程等待,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来换唤醒该线程。
    • notify():唤醒在此同步监视器上等待的单个线程。如果有多个在等待,则任意选择一个唤醒。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。
    • notifyAll():唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。

    6.2 使用Condition控制线程通信

    如果程序使用Lock对象保证同步,则不能使用wait()、notify()或notifyAll()方法进行线程通信。

    Java提供了Condition类来针对这种情况下的线程通信。Condition实例可由Lock对象的newCondition()方法获得。与传统线程通信相似,Condition类提供了三个方法:

    • await():与wait()类似,使当前线程等待,直到其他线程调用该Condition的signal()方法或signalAll()方法来唤醒该线程。
    • signal():唤醒在次Lock对象上等待的单个线程。如果有多个线程在该Lock对象上等待,则任意选择一个唤醒。只有当前线程放弃对该Lock对象的锁定后,才可以执行被唤醒的线程。
    • signalAll():唤醒在此Lock对象上等待的所有线程。只有当前线程放弃对该Lock对象的锁定后,才可以执行被唤醒的线程。
    //使用newCondition()方法创建Condition实例
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    
    ...
        lock.lock();
    	try {
            if (...) {
                condition.await();		//使当前线程等待
            } else {
                condition.signalAll();	//唤醒在该Lock对象上等待的所有线程
            }
        } finally {
            lock.unlock();
        }
    ...
    

    6.3 使用阻塞队列(BlockingQueue)控制线程通信

    BlockingQueue是Queue的子接口。当生产者线程试图向BlockingQueue中放入元素时,如果该队列已满,则该线程被阻塞;当消费者线程试图从BlockingQueue中取出元素时,如果该队列已空,则该线程被阻塞。

    BlockingQueue中支持阻塞的方法为:put()和take()

    使程序的两个或多个线程交替向BlockingQueue中放入、取出元素,可以很好的控制线程通信。



    完整笔记下载:

    pdf版链接:https://pan.baidu.com/s/1AxAo3ZLwf5EwUV6i6yWp8Q
    提取码:6jom

    md文件链接:https://pan.baidu.com/s/1tX0HCJteEVwCoXC0Hkw68Q
    提取码:99t1

    展开全文
  • C#多线程笔记

    2012-05-28 12:10:00
    C#多线程笔记 每个窗体都有自己的都在不同的线程上运行,如果需要在窗体之间交互,就需要在线程之间交互。
  • Java 多线程笔记(1)——线程简介 Java 多线程笔记(2)——创建/启动线程 Java 多线程笔记(3)——线程的生命周期 Java 多线程笔记(4)——控制线程 Java 多线程笔记(5)——线程同步 Java 多线程笔记(6)——...

    Java菜鸟,初学多线程,使用的教材是《疯狂java讲义(第四版)》。有理解不到位的地方,欢迎批评指正~
    (文章末尾有整个笔记的pdf版本和md版本)


    Java 多线程笔记(1)——线程简介
    Java 多线程笔记(2)——创建/启动线程
    Java 多线程笔记(3)——线程的生命周期
    Java 多线程笔记(4)——控制线程
    Java 多线程笔记(5)——线程同步
    Java 多线程笔记(6)——线程通信



    5. 线程同步


    5.1 线程安全问题

    当程序中有变量的读取写入判断操作时,可能会引起线程不安全。

    例:假如往一个列表中存放数据时分为两步:

    1. 在第n个位置存放元素
    2. 增大n的值

    假如此时有两个线程A和B往一个列表中存放数据,n的初始值为0。A先将数据存放到位置n=0。但是这个时候线程A被暂停,线程B开始运行。因为此时n的值还是0(由于A被中断,n的值并未增加),所以B也把元素存放到了位置n=0。然后,A和B继续执行完毕,结束时n=2。此时线程就不安全了,列表中只有一个值但是n却等于2。

    线程安全问题都是由全局变量静态变量引起的。

    一般来说,如果每个线程中只对全局变量和静态变量有读操作,而无写操作,线程是安全的。如果多个线程同时执行写操作,就可能影响线程安全。


    5.2 解决线程安全问题

    5.2.1 同步代码块

    为了解决线程安全问题,Java引入同步监视器来解决这个问题。使用同步监视器的通用方法是同步代码块。语法如下:

    //括号中的obj即同步监视器
    synchronized(obj) {
        //...
    }
    

    上面代码的含义是:线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。

    任何时刻只能有一个线程可以获得对某个同步监视器的锁定,当同步代码块执行完成后,该线程会释放对该同步监视器的锁定。

    任何对象都可以作为同步监视器。通常推荐使用可能被并发访问的共享资源作为同步监视器(例如上例中,列表可以作为同步监视器)。

    5.2.2 同步方法

    使用synchronized关键字修饰的方法称为同步方法。同步方法的同步监视器是this,也就是调用该方法的对象。

    public synchronized 返回值类型 方法名() {...}
    

    通过使用同步方法可以非常方便的实现线程安全的类,线程安全的类有如下特征:

    • 该类的对象可以被多个线程安全的访问
    • 每个线程调用该对象的任意方法之后都将得到正确结果
    • 每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态

    不可变类总是线程安全的,因为它的对象状态不可改变

    线程安全是以降低程序的运行效率作为代价的,为了减少线程安全所带来的负面影响,程序可以采用以下策略:

    • 不要对线程安全类的所有方法都进行同步,只对那些会改变竞争资源的方法进行同步。
    • 如果有单线程和多线程两种运行环境,则应该为该可变类提供两种版本:线程不安全版本和线程安全版本(例如StringBuilder和StringBuffer,StringBuilder在单线程环境下保证较好性能,StringBuffer保证线程安全)

    程序无法显式释放对同步监视器的锁定,线程会在如下几种情况释放对同步监视器的锁定

    • 当前线程的同步方法、同步代码块执行结束,当前线程即释放同步监视器
    • 当前线程在同步方法、同步代码块中遇到break、return终止了该代码块、该方法的继续执行
    • 当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致了该代码块、该方法异常结束时,当前线程将会释放同步监视器。
    • 当前线程执行同步代码块或同步方法时,程序执行了同步监视器对象的wait()方法,则当前线程暂停,并释放同步监视器

    在以下情况下,线程不会释放同步监视器

    • 线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法来暂停当前线程的执行,当前线程不会释放同步监视器
    • 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放同步监视器
    5.2.3 同步锁(Lock)

    通过显式定义同步锁对象来实现同步,在这种机制下,同步锁由Lock对象充当。

    class X {
        //定义锁对象
        //ReentrantLock 可重入锁,比较常用
        private final ReentrantLock lock = new ReentrantLock();
        
        //定义需要保证线程安全的方法
        public void m() {
            //加锁
            lock.lock();
            try {
                //。。。
            } finally {
                //使用finally块来保证释放锁
                lock.unlock();
            }
        }
    }
    

    5.3 死锁

    当两个线程相互等待对方释放同步监视器时,就会发生死锁。出现死锁时,整个程序不会发生异常,也不会给出提示,所有线程处于阻塞状态,无法继续。Java虚拟机没有监测也没有采取措施来处理死锁情况,所以应采取措施避免死锁情况出现。

    例子:

    进程1锁住A ——> 进程2锁住B ——> 进程1试图锁住B(失败,因为B已经被进程2锁住,阻塞)——> 进程2试图锁住A(失败,因为A已经被进程1锁住,阻塞)——> 进程1永久等待 ——> 进程2永久等待

    造成死锁的原因:

    • 系统资源的竞争

    • 进程运行推进顺序不当

    产生死锁的四个必要条件:

    • 互斥条件:指进程对所分配到的资源进行排他性使用,记载一段时间内某资源只由一个进程占用。如果此时还有其他进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
    • 请求与保持条件:进程已经保持了至少一个资源,但是又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞。同时对自己已获得的资源保持不放。
    • 不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能主动释放)。
    • 循环等待条件:发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0, P1, P2, …, Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

    上述四个条件只要其中之一不满足,就不会发生死锁。

    引用自:Kevin_Zhang

    死锁的避免与预防

    思路:设计时注意避免使产生死锁的四个必要条件同时成立

    • 互斥条件:资源互斥是固有特性无法改变

    • 破坏请求与保持条件

      1. 静态分配:每个进程在开始执行时就申请他所需要的全部资源
      2. 动态分配:每个进程在申请所需要的资源时它本身不占用系统资源
    • 破坏不可剥夺条件:一个进程不可获得其所需要的全部资源便处于等待状态,等待期间他占用的资源将被隐式的释放重新加入到系统的资源列表中,可以被其他进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。

    • 破坏循环等待条件:采用资源有序分配的基本思想。将系统中的资源顺序进行编号,将紧缺的、稀少的资源采用较大的编号,申请资源时必须按照编号的顺序执行,一个进程只有较小编号的进程才能申请较大编号的进程。

    引用自:ZWE7616175



    完整笔记下载:

    pdf版链接:https://pan.baidu.com/s/1AxAo3ZLwf5EwUV6i6yWp8Q
    提取码:6jom

    md文件链接:https://pan.baidu.com/s/1tX0HCJteEVwCoXC0Hkw68Q
    提取码:99t1

    展开全文
  • Java 多线程笔记(1)——线程简介 Java 多线程笔记(2)——创建/启动线程 Java 多线程笔记(3)——线程的生命周期 Java 多线程笔记(4)——控制线程 Java 多线程笔记(5)——线程同步 Java 多线程笔记(6)——...
  • Java多线程笔记

    2018-03-11 16:34:39
    多线程学习笔记,好资源。包括线程基础等知识多线程学习笔记,好资源。包括线程基础等知识
  • Java 多线程笔记(1)——线程简介 Java 多线程笔记(2)——创建/启动线程 Java 多线程笔记(3)——线程的生命周期 Java 多线程笔记(4)——控制线程 Java 多线程笔记(5)——线程同步 Java 多线程笔记(6)——...
  • 狂神说多线程笔记整理 笔记总结来自狂神说Java多线程详解 目录狂神说多线程笔记整理一、线程简介1.多任务2.多线程3.程序.进程.线程4.Process与Thread5.核心概念二、线程实现1.线程创建(三种方法)1.1继承Thread类...
  • Java 多线程笔记(1)——线程简介 Java 多线程笔记(2)——创建/启动线程 Java 多线程笔记(3)——线程的生命周期 Java 多线程笔记(4)——控制线程 Java 多线程笔记(5)——线程同步 Java 多线程笔记(6)——...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,088
精华内容 10,435
关键字:

多线程笔记