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

    2014-11-15 04:16:21
    Java多线程编程总结 http://lavasoft.blog.51cto.com/62575/27069

    Java多线程编程总结

    http://lavasoft.blog.51cto.com/62575/27069

    展开全文
  • Java多线程笔记

    千次阅读 2015-07-12 16:00:09
    调用new Thread(runnable).start()方法启动线程,将会在线程中调用对应的runnalbe.run方法 2、中断线程的方式:调用interrupt方式,会置位线程中断状态。检查这个中断位可判断线程是否被中断:Thread.currentThread...
    1、使用new Thread(runnableObj)方式,而非继承自Thread。
    对于耗时的任务,应放到线程中执行
    调用new Thread(runnable).start()方法启动线程,将会在线程中调用对应的runnalbe.run方法
    2、中断线程的方式:调用interrupt方式,会置位线程中断状态。检查这个中断位可判断线程是否被中断:Thread.currentThread().isInterrupted().
    currentThread可用于获取当前线程。
    sleep方法会清除中断状态并抛出InterruptedException。
    interrupt()会向线程发中断请求,并将中断状态置为true。
    interrupted()方法会检测是否线程被中断了,如果是会清除中断状态。


    线程状态:New,Runnable可运行(调用start后的状态,正在执行的线程状态以及等待执行的都是可运行),Blocked被阻塞,Waitting,Timed waiting计时等待,Terminated。


    被阻塞的情况:1、等待锁被释放;2、当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态;方法带有超时参数,超时时会进入计时等待状态。如Thread.sleep,Object.wait(),Thread.join(),Lock.tryLock(),Condition.await()


    3、join()等待终止指定的线程,join(long mills)等待指定线程死亡或经过指定的毫秒数;
    Thread.State getState()获取线程的状态
    4、线程继承自父线程的优先级。用setProperty调整优先级,取值0~10,值越大优先级越高。
    static void yield()此方法导致当前执行线程处于让步状态,有同优先级线程存在时,会优先执行。
    5、this.setDaemon(true)使线程转换为守护线程,此方法必须在线程启动前调用。守护线程的用途是为其他线程提供服务。当只剩下守护线程时,虚拟机退出。守护线程应该永远不要去访问固定资源,如文件、数据库,因为它在任何时候都可能在一个执行过程中发生中断。
    6、线程的run不能抛出被检测的异常。未被检测的异常会导致线程终止,线程死亡前异常会被传递到一个用于未捕获异常的处理器。该处理器实现了Thread.UncaughtExcetptionHandler接口。没安装默认处理器的话,默认处理器为空。不为独立的线程安装处理器,其处理器就是ThreadGroup对象
    不要在Catch语句中处理可被传递的异常。


    javap -c -v Bank 用于对Bank.class进行反编译


    7、采用synchronized保证代码块的并发访问。
    ReentrantLock是一个锁对象,可用于控制并发。在一个公共访问代码中声明一个锁对象。在try之前获得锁,finally里释放锁。而非将锁对象作为线程的成员。
    锁是可重入的,线程可以重复获取已持有的锁。锁保持一个持有计数,在临界区内调用其他方法时,计数加1,所调用的方法退出时,锁减1.
    留心临界区的异常处理,不要因异常而导致跳出临界区。
    8、条件对象用于线程等待某个条件满足时执行操作。单纯的锁无法满足这种场景。
    一个锁可以关联多个条件变量Condition。bankLock.newCondition()创建锁关联的条件变量。在临界区内,while(condition no statisfy)condition.await();在循环体中调用是必须的。 通过调用条件变量中的await方法会进入该条件的等待集,阻塞,等待另一个线程调用同一条件上的signalAll方法(会解除所有等待这一条件的线程的阻塞,使得被解除阻塞的线程可以在当前线程退出阻塞之后,通过竞争实现对象的访问)。signal()方法则是随机解除一个阻塞的线程,这个方式需保证被解除阻塞的线程可以执行,否则会造成死锁。
    每个条件对象管理那些已经进入了被保护的代码段,但还不能运行的线程。


    每个对象内都有一把锁,要调用synchronized声明的对象成员方法,必须事先获得内部的对象锁。
    内部的对象锁只有一个关联的条件对象,wait会将线程添加到等待集中,notify/notifyAll会解除等待线程的阻塞状态。只能在synchronized内部使用wait和notify方法实现条件对象等待某个条件实现的功能。模式与await和signal相似。
    一般不要用synchronized和Condition,优先用synchronized。


    线程有本地缓存和寄存器,可以暂存内存中的值。如果使用锁来执行并发访问共享变量,编译器被要求在必要的时候刷新本地缓存(更新共享变量在本地的值)来保持锁的效应。
    volatile为同步访问提供了免锁机制,但是不保证原子性。如果共享变量除了赋值外,不完成其他操作,可以将其声明为volatile。
    atomic对象可以原子方式对变量做加减。


    9、public static final ThreadLocal<SimpleDateFormat> dataFormat= 
    new ThreadLocal<SimpleDateFormat>(){
    protect SimpleDateFormat initialValue(){
    return new SimpleDateFormat("yyyy-MM-dd");
    }
    }


    10、锁超时: if(myLock.tryLock(100,TimeUnit.MILLISECONDS)){...} 超时时抛出InterruptedException,可用于打破死锁。
    myCondition.await(100,TimeUnit.MILLISECONDS)


    11、读线程多写线程少用ReentrantReadWriteLock。
    private rwLock =  new ReentrantReadWriteLock();
    rLock=rwLock.readLock();该所被所有读线程共用,会排斥写操作在读之前用rLock.lock();结束后用rLock.unlock();
    wLock=rwLock.writeLock();排斥其他的读操作和写操作n。在写之前用wLock.lock();结束后用wLock.unlock();


    12、阻塞队列BlockingQueue(这个有几种继承类:LinkedBlockingQueue, LinkedBlockingDeque, ArrayBlockingQueue)就是一个生产者消费者模型中的用于存放共享数据的队列。该队列有考虑生产者消费者间的并发操作,处理生产者消费者速度的负载平衡。用offer添加一个元素、poll移出并返回队头、peek返回队头元素(这三种操作可指定操作的超时时间)。
    PriorityBlockingQueue优先队列。


    13、线程安全集合:阻塞队列、ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet(这两个是线程安全的有序集,需事先Comparable接口), ConcurrentLinkedQueue. 这些集合的size()内部需要通过遍历来确定集合大小,这与一般的集合不同。
    这些集合返回的是弱一致性的迭代器,不一定能返回被修改后的值,但不会将同一个值返回两次,不会抛出ConcurrentModificationException。
    ConcurrentHashMap<E>(int initialCapacity, float loadFactor, int concurrentLevel);中参数是指定集合的初始容量,默认为16.concurrentLevel是并发写者线程的估计数目,表明可供多达16个写进程同时写,多了会阻塞剩下的线程。
    ConcurrentHashMap.putIfAbsent(k,v)是在该键不存在时插入kv对,否则返回键k对应的值。




    写数组的拷贝:
    CopyOnWriteArrayList和CopyOnWriteArraySet。写线程对底层数据做修改。如果读线程数大于写线程数,则这类集合很适合。读写可不用同步就可保持一致性。


    任何集合类通过同步包装器可变为线程安全的,通过给集合加入锁来实现的,这不推荐使用,因为还是需要在访问的代码中加入synchronized(synchashMap){...},推荐使用ConcurrentXXX集合:
    List<E> syncArrayList = Collections.synchronizedList(new ArrayList<E>());
    HashMap<K,V> syncHashMap = Collections.synchronizedMap(new HashMap<K,V>());
    对于经常被修改的数组列表,采用synchronized(arrayList){}会比CopyOnWriteArrayList性能更好。




    14、回调Callable和Future。 Runnalbe是无返回值无参数的异步方法,Callable和Future有返回值。Callable<E>{ E call();}只有一个方法返回值类型为E的call().
    Future保存了异步计算结果,其get(long timeout,TimeUnit)可指定超时时间,超时时中断。如果Future还在执行,则isDone()返回false。cancle()方法可取消该运算。


    FutureTask包装器,可将Callable转化为Future何Runnable。
    Callable<Integer> myCompution=..;
    FutureTask<Integer> task= new FutureTask<Integer>(myCompution);//构造一个既是Future又是Runnable的对象。
    Thread t= new Thread(task);
    t.start();
    ...
    Integer result=task.get();//对get调用会阻塞直到有可获得的结果或者超时为止。


    15、执行器Executor
    如果程序中有大量生命期很短的线程,最好使用线程池。线程池中包含了许多准备运行的空闲线程。将Runnable交给线程池,就会有一个线程调用Runnable.run()。run退出时线程又回到线程池等待下一次运行。
    使用线程池可减少并发线程数。
    Executor中有许多静态方法可用于构建线程池:newCachedThreadPool空闲线程被保存60s;newFixedThreadPool固定线程数且空闲线程一直保存,如果任务数大于线程数,未得到执行的任务会放到队列中等待空闲线程可用;newSingleThreadPool只有一个线程,用于顺序执行。这些方法返回实现了ExecutorService接口的ThreadPoolExecutor对象。
    可用ExecutorService接口中的Future<?> submit(Runnable,T result);Future<?>submit(Callable<T> Task)方法提交Runnable和Callable对象给ExecutorService。
    线程池用完后调用shutdown()关闭线程池。


    步骤:
    a、Executors.newFixedThreadPool() 
    b、submit提交Runnable或Callable对象;
    c、获取Future对象result,并调用result.get();
    d、关闭线程池shutdown()




    15、预定执行(定时任务)
    ScheduledExecutorService接口中有为预定执行或重复执行的任务设计的方法。
    ScheduledExecutorService ss=Executors.newScheduledThreadPool();
    schedule(Callable/Runnable,initDelayTime,TimeUnit);
    scheduleAtFixedRate(Callable/Runnable,initDelayTime,long period,TimeUnit);//每隔period执行一次


    16、控制任务组
    Executor可用于控制一组相关任务。
    invokeAny:多个任务执行,只要有一个执行完成就可以结束了。
    invokeAll:多个任务执行,所有任务都执行完成才可以结束。使用方式如下:
    List<Callable<T>> tasks=...; 
    List<Future<T>> results=executor.invokeAll(tasks);
    for(Future<T>res:results){//顺序遍历在第一个任务耗时很长的情况下会花很多时间进行等待,推荐用ExecutorCompletionService按结果产生顺序进行保存,更有效
    processFuturer(result.get());
    }


    17、fork-join框架(大任务划分为小任务,并行执行后merge)
    RecursiveTask用于有计算结果返回,RecursiveAction用于无计算结果返回。二者的compute用于生成并调用子任务并合并结果。
    class Counter extends RecursiveTask<Integer>{//分治算法
    protect Integer compute(){
    if(to-from<THRESHOLD){直接执行(单任务)}
    else{
    int mid=(low+high)>>1;
    Counter first=new Counter(from,mid);//拆分子任务
    Counter second=new Counter(mid+1,high);
    invokeAll(first,second);//调度所有子任务
    return first.join()+second.join();//合并结果
    }
    }
    }
    main(){
    ForkJoinPool pool=new ForkJoinPool();
    pool.invoke(counter);
    System.out.println(counter.join());
    }


    18、同步器
    提供了实现线程间相互合作的类:
    CyclicBarrier:等待一定数目的线程都到达一个公共屏障,在执行一个处理屏障的动作。


    CyclicBarrier barrier=new CyclicBarrier(numThreads,barrierAction);//当numThreads个线程都到达屏障时执行barrierAction
    Runnable{
    public void run(){
    doSomething...
    barrier.await();//等待直到屏障打开,可设置超时时间,超时时抛异常,会导致其他等待await的线程都抛BrokenBarrierException异常。
    ...
    }
    }


    CountDownLatch:允许等待直到计数器为0。用于当一个或多个线程需等到指定数目事件发生时。这是一次性的,只可用一次。
    Exchanger:允许两个线程在要交换对象准备好时交换对象。两个线程在同一个数据结构的两个不同实例上,一个向实例添加数据,另一个用于清除数据
    Semaphore:允许线程等待直到被允许执行为止。用于限制访问资源的线程数。
    信号量管理了许多permits,用于限制通过的线程数量。信号量仅维护一个计数。其他线程通过调用release()释放许可permits。


    SynchronousQueue:允许一个线程把对象交给另一个线程。在没显式同步时,两个线程将一个对象从一个线程传到另一个线程。
    展开全文
  • 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多线程笔记--顺序执行

    千次阅读 2019-05-26 17:58:42
    文章目录java多线程笔记--多线程顺序执行1.java多线程笔记--顺序执行2.java多线程笔记--循环顺序打印问题2.1通过Lock、3个Condition的等待唤醒机制和状态变量判断,来控制3个线程输出顺序2.2通过Lock和状态变量判断...

    java多线程笔记–多线程顺序执行


    参考:https://www.cnblogs.com/xiaoxi/p/8035725.html

    https://blog.csdn.net/hefenglian/article/details/82596072

    https://blog.csdn.net/Evankaka/article/details/80800081

    1.java多线程笔记–顺序执行

    1.使用join
    如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B
    2.使用CountDownLatch
    await方法阻塞当前线程,当CountDownLatch减为0时就代表条件已成熟,所有因调用await方法而阻塞的线程都会被唤醒
    3.使用阻塞队列,利用队列的FIFO特性
    4.使用newSingleThreadExecutor内部,线程池的newSingleThreadExecutor内部使用一个容量不限的阻塞队列,同3类似
    

    2.java多线程笔记–循环顺序打印问题

    解决:3个线程1、2、3依次执行打印ABC,但是实际处理的时候不一定先执行线程1打印A,具体跟判断逻辑有关,比如先执行了线程3,但是run中判断满足条件才输出。

    2.1通过Lock、3个Condition的等待唤醒机制和状态变量判断,来控制3个线程输出顺序

    public class PrintABCByLockAndCondition {
        private static Lock lock = new ReentrantLock();
        private static Condition conditionA = lock.newCondition();
        private static Condition conditionB = lock.newCondition();
        private static Condition conditionC = lock.newCondition();
        private static int status = 0;
    
        public static void main(String[] args) {
            new PrintABCByLockAndCondition().printABC();
        }
    
        public void printABC() {
            ExecutorService service = Executors.newFixedThreadPool(3);
            //线程的执行顺序跟提交顺序无关
            service.execute(new RunnableC());
            service.execute(new RunnableB());
            service.execute(new RunnableA());
            service.shutdown();
        }
    
        private class RunnableA implements Runnable {
            @Override
            public void run() {
                try {
                    lock.lock();
                    while (true) {
                        while (status % 3 != 0) {//注意这里是不等于0,也就是说没轮到该线程执行,之前一直等待状态
                            conditionA.await();//释放了锁,进入阻塞等待,依赖C唤醒
                        }
                        System.out.print("A");
                        status++;
                        conditionB.signal(); // A执行完唤醒B线程
                    }
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
    
            }
        }
    
        private class RunnableB implements Runnable {
            @Override
            public void run() {
    
                try {
                    lock.lock();
                    while (true) {
                        while (status % 3 != 1) {
                            conditionB.await();
                        }
                        System.out.print("B");
                        status++;
                        conditionC.signal(); // B执行完唤醒C线程
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
    
            }
        }
    
        private class RunnableC implements Runnable {
            @Override
            public void run() {
                try {
                    lock.lock();
                    while (true) {
                        while (status % 3 != 2) {
                            conditionC.await();
                        }
                        System.out.println("C");
                        status++;
                        conditionA.signal(); // C执行完唤醒A线程
                    }
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    
    

    2.2通过Lock和状态变量判断,来控制3个线程输出顺序

    public class PrintABCByLock {
        private static Lock lock = new ReentrantLock();
        private static int status = 0;
    
        public static void main(String[] args) {
            new PrintABCByLock().printABC();
        }
    
        public void printABC() {
            ExecutorService service = Executors.newFixedThreadPool(3);
            //线程的执行顺序跟提交顺序无关
            service.execute(new RunnableC());
            service.execute(new RunnableB());
            service.execute(new RunnableA());
            service.shutdown();
        }
    
        private class RunnableA implements Runnable {
            @Override
            public void run() {
                while (true) {
                    try {
                        lock.lock();
                        while (status % 3 == 0) {
                            System.out.print("A");
                            status++;
                        }
                    } finally {
                        lock.unlock();
                    }
                }
            }
        }
    
        private class RunnableB implements Runnable {
            @Override
            public void run() {
                while (true) {
                    try {
                        lock.lock();
                        while (status % 3 == 1) {
                            System.out.print("B");
                            status++;
                        }
                    } finally {
                        lock.unlock();
                    }
                }
            }
        }
    
        private class RunnableC implements Runnable {
            @Override
            public void run() {
                while (true) {
                    try {
                        lock.lock();
                        while (status % 3 == 2) {
                            System.out.println("C");
                            status++;
                        }
                    } finally {
                        lock.unlock();
                    }
                }
    
            }
        }
    }
    

    2.3通过3个信号量,每个信号量的最大许可为1,来控制3个输出顺序

    public class PrintABCBySemaphore {
    
        //信号量,表示可用的许可数量,用于控制同时容许访问的线程数量
        public Semaphore s1 = new Semaphore(1);
        public Semaphore s2 = new Semaphore(0);
        public Semaphore s3 = new Semaphore(0);
    
        public static void main(String[] args) {
            new PrintABCBySemaphore().printABC();
        }
    
        public void printABC() {
            ExecutorService exe = Executors.newFixedThreadPool(3);
            exe.execute(new RunnableC());
            exe.execute(new RunnableA());
            exe.execute(new RunnableB());
            exe.shutdown();
        }
    
        private class RunnableA implements Runnable {
            @Override
            public void run() {
                while (true) {
                    try {
                        s1.acquire();//获取信号量,s1 - 1
                        System.out.print("A");
                        s2.release();//释放信号量,s2 + 1
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    
        private class RunnableB implements Runnable {
            @Override
            public void run() {
                while (true) {
                    try {
                        s2.acquire();//获取信号量,s2 - 1
                        System.out.print("B");
                        s3.release();//释放信号量,s3 + 1
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    
        private class RunnableC implements Runnable {
            @Override
            public void run() {
                while (true) {
                    try {
                        s3.acquire();//获取信号量,s3 - 1
                        System.out.println("C");
                        s1.release();//释放信号量,s1 + 1
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    2.4通过Atomic原子自增和3个线程的判断逻辑,来控制3个线程输出顺序

    public class PrintABCByAtomic {
        private AtomicInteger status = new AtomicInteger(0);
    
        public static void main(String[] args) {
            new PrintABCByAtomic().printABC();
        }
    
        public void printABC() {
    
            ExecutorService service = Executors.newFixedThreadPool(3);
            //线程的执行顺序跟提交顺序无关
            service.execute(new RunnableC());
            service.execute(new RunnableB());
            service.execute(new RunnableA());
            service.shutdown();
        }
    
        private class RunnableA implements Runnable {
            @Override
            public void run() {
                while (true) {
                    if (status.get() % 3 == 0) {
                        System.out.print("A");
                        status.getAndIncrement();
                    }
                }
            }
        }
    
        private class RunnableB implements Runnable {
            @Override
            public void run() {
                while (true) {
                    if (status.get() % 3 == 1) {
                        System.out.print("B");
                        status.getAndIncrement();
                    }
                }
            }
        }
    
        private class RunnableC implements Runnable {
            @Override
            public void run() {
                while (true) {
                    if (status.get() % 3 == 2) {
                        System.out.println("C");
                        status.getAndIncrement();
                    }
                }
    
            }
        }
    }
    
    展开全文
  • Java多线程笔记详解

    2018-10-09 15:50:42
    Java多线程学习笔记1之多线程基础 内容: 1) 基本概念以及线程的实现方法   Java多线程学习笔记2之多线程基础 内容: 1) 数据同步 2) 非线程安全情况以及处理方法 3) Java内存模型 4) Thread.current...
  • Java多线程笔记总结

    千次阅读 2015-12-22 10:05:55
    1.线程的三种创建方式参考之前的总结: 多线程-创建线程的三种方式对比三种方式: 通过继承Thread类实现 通过实现Runnable接口 实现Callable接口 第1种方式无法继承其他类,第2,3种可以继承其他类;第2,3种方式...
  • 内推进阿里,面试之前阿里学长给了一份Java多线程笔记,让我轻松拿下阿里一面。 以下这些技术点都是阿里学长的全解析笔记中总结的内容: 笔记内容介绍: 基础篇 进程与线程基本概念 Java多线程入门类和接口...
  • 内推进阿里,面试之前阿里学长给了一份Java多线程笔记,让我轻松拿下阿里一面。 以下这些技术点都是阿里学长的全解析笔记中总结的内容: 笔记内容介绍: 由于笔记内容过多,因此为了避免影响到大家的阅读...
  • method1 start method1 execute method1 end method2 start method2 execute method2 end
  • public class MyWaitNotify3{ MonitorObject myMonitorObject = new MonitorObject(); boolean wasSignalled = false; public void doWait(){ synchronized(myMonitorObject){ while(!wasSignalled){ ...
  • java多线程编程核心技术】1.java多线程技能-笔记总结 【java多线程编程核心技术】2.对象及变量的并发访问(上)-笔记总结 【java多线程编程核心技术】2.对象及变量的并发访问(下)-笔记总结 【java多线程编程...
  • Java多线程复习笔记

    千次阅读 2020-03-22 21:42:19
    Java多线程复习笔记 1、基础概要 ​ Java线程的创建方法有三种,第一种是通过实现Runnable接口,第二种是通过继承Thread类本身,第三种是通过 Callable 和 Future 来创建线程。第一种和第二种,都是通过重写run方法...
  • Java 多线程总结笔记

    千次阅读 2018-09-19 10:21:56
    Java多线程总结笔记 实现多线程的方法 查看Thread类的源码,可以发现它实现了Runnable接口,然后在自己的run方法中调用了Runnable的run方法。这里其实就是静态代理这一设计模式,Thread是代理角色,而Runnable则是...
  • Java多线程学习笔记

    千次阅读 2016-09-30 15:24:04
    Java多线程学习笔记
  • 万字图解Java多线程

    万次阅读 多人点赞 2020-09-06 14:45:07
    java多线程我个人觉得是javaSe中最难的一部分,我以前也是感觉学会了,但是真正有多线程的需求却不知道怎么下手,实际上还是对多线程这块知识了解不深刻,不知道多线程api的应用场景,不知道多线程的运行流程等等,...
  • Java 多线程学习笔记

    千次阅读 2014-06-16 08:00:17
    多线程笔记目录 ·多线程的概念 (·)线程和进程 1.进程的概念 2.线程的概念 3.多线程的特性 4.注意区别并行和并发   ·多线程的创建和启动 (·)实现多线程的综述 1.综述 2.为什么要覆盖run()方法? 3. run()方法和...
  • java多线程详细学习笔记(高级部分)
  • Java多线程学习笔记 - 1

    千次阅读 2021-03-12 21:44:02
    多任务 概述: 多任务就是同时运行多个任务。...实现方式: 多线程或多进程。 进程与线程介绍: 进程 概述: 线程 概述: 进程与线程之间的关系 一个进程内含有一个或多个线程,但至少含有一个线程。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 107,574
精华内容 43,029
关键字:

java多线程笔记

java 订阅