美文网首页
Java基础|多线程

Java基础|多线程

作者: zhoulikai | 来源:发表于2022-12-03 23:44 被阅读0次
三个线程依次执行

思路一:使用join, join底层使用wait使得当前线程终止,c++去唤醒

public class ThreadJoin {

    private static class Thread1 extends Thread {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+ "----------------");
        }
    }

    private static class Thread2 extends Thread {
        private Thread1 thread1;
        private Thread2(Thread1 thread1) {
            this.thread1 = thread1;
        }
        @Override
        public void run() {
            try {
                this.thread1.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName()+ "----------------");
        }
    }

    private static class Thread3 extends Thread {
        private Thread2 thread2;
        private Thread3(Thread2 thread2){
            this.thread2 = thread2;
        }
        @Override
        public void run() {
            try {
                this.thread2.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName()+ "----------------");
        }
    }

    public static void main(String[] args) {
        Thread1 thread1 = new Thread1();
        thread1.setName("线程一");
        thread1.start();
        Thread2 thread2 = new Thread2(thread1);
        thread2.setName("线程二");
        thread2.start();
        Thread3 thread3 = new Thread3(thread2);
        thread3.setName("线程三");
        thread3.start();
    }
}

思路二:使用一个变量 三个值一次唤醒

public class ThreadJoin {

    private static int status = 0;
    private static Object lock = new Object();
    private static class Thread1 extends Thread {

        @Override
        public void run() {
            synchronized (lock) {
                while (status != 0) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println(Thread.currentThread().getName()+ "----------------");
                status = 1;
                lock.notify();
            }

        }
    }

    private static class Thread2 extends Thread {
        @Override
        public void run() {
           synchronized (lock) {
               while (status != 1) {
                   try {
                       lock.wait();
                   } catch (InterruptedException e) {
                       throw new RuntimeException(e);
                   }
               }
               System.out.println(Thread.currentThread().getName()+ "----------------");
               status = 2;
               lock.notify();
           }

        }
    }

    private static class Thread3 extends Thread {

        @Override
        public void run() {
            synchronized (lock) {
                while (status != 2) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(Thread.currentThread().getName()+ "----------------");
                }
            }

        }
    }

    public static void main(String[] args) {
        Thread1 thread1 = new Thread1();
        thread1.setName("线程一");
        thread1.start();
        Thread2 thread2 = new Thread2();
        thread2.setName("线程二");
        thread2.start();
        Thread3 thread3 = new Thread3();
        thread3.setName("线程三");
        thread3.start();
    }
}

二、线程状态

1、新建状态 (新建thread)
2、就绪状态(调用start)
3、运行状态 (执行run内的方法)
4、终止状态 (run方法内执行结束)
5、阻塞状态(synchroized 、调用wait,join, 唤醒调用notify让线程处于就绪状态)
6、等待超时状态(wait(100))
7、等待状态 (wait)

三、线程种类

1、守护线程:依赖用户线程,用户线程退出了,守护线程也退出,例如垃圾回收线程(调用Thread setDaemon(true))
2、用户线程:独立存在的,不会因为其他用户线程退出而退出

public class ThreadDeamon {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("子线程正在运行");
                    try {
                        Thread.sleep(1 * 1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        thread.setDaemon(true);
        thread.start();
        System.out.println("主线程结束");
    }
}

四、线程终止

1、使用interrupt()方法,wait\sleep\join会抛异常
2、使用标志位

public class ThreadFinish {

    public static class Thread1 extends  Thread {
        private volatile boolean isRun = true;
        @Override
        public void run() {
            while (isRun) {

                try {
                    Thread.sleep(1 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //线程终止前可以做的操作
            System.out.println("线程终止了");
        }

        public void startThread() {
            isRun = true;
            this.start();
        }
        public void stopThread() {
            isRun = false;
            this.interrupt();
        }
    }
    public static void main(String[] args) {
        Thread1 thread1 = new Thread1();
        thread1.startThread();

        try {
            Thread.sleep(3 * 1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        thread1.stopThread();
    }
}

五、ReentrantLock、Condition使用 两个线程依次打印

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo {
    private ReentrantLock reentrantLock = new ReentrantLock();
    private Condition condition = reentrantLock.newCondition();
    private int status = 1;

    private void method1() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    reentrantLock.lock();
                    while (true) {
                        while (status != 1) {
                            condition.await();
                        }
                        System.out.println(Thread.currentThread().getName());
                        Thread.sleep(1 * 1000);
                        status = 2;
                        condition.signal();
                    }

                } catch (Exception e) {

                } finally {
                    reentrantLock.unlock();
                }
            }
        }, "线程一").start();
    }

    private void method2() {
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    reentrantLock.lock();
                    while (true) {
                        while (status != 2) {
                            condition.await();
                        }
                        System.out.println(Thread.currentThread().getName());
                        Thread.sleep(1 * 1000);
                        status = 1;
                        condition.signal();
                    }

                }catch (Exception e) {

                } finally {
                    reentrantLock.unlock();
                }
            }
        }, "线程二").start();
    }
    public static void main(String[] args) {
        ReentrantLockDemo reentrantLockDemo = new ReentrantLockDemo();
        reentrantLockDemo.method1();
        reentrantLockDemo.method2();
    }
}

六、sleep() wait区别

sleep:不释放线程锁,是Thread内方法
wait:释放线程锁,必须放在synchronized中 是object类方法

七、FutureTask Callable 使用

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class FutureTaskDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("执行开始");
                Thread.sleep(1 * 1000);
                System.out.println("执行结束");
                return 1;
            }
        };
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        new Thread(futureTask).start();
        //阻塞等待结果
        Integer result = futureTask.get();
        System.out.println("执行结果:" + result);
    }
}

八、通过wait notify实现FutureTask Callable

public interface MyCallable<V> {
    V call() throws Exception;
}
public class MyFutureTask<V> implements Runnable{
    private MyCallable<V> myCallable;
    private Object lock = new Object();
    private V result;
    public MyFutureTask(MyCallable<V> myCallable) {
        this.myCallable = myCallable;
    }
    @Override
    public void run() {
        try {
            result = myCallable.call();
            synchronized (lock) {
                lock.notify();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public V get() {
        synchronized (lock) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        return result;
    }
}

public class MyFutureTaskDemo {

    public static void main(String[] args) {
        MyCallable<Integer> myCallable = new MyCallable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("线程执行开始");
                Thread.sleep(1 * 1000);
                System.out.println("线程执行结束");
                return 1;
            }
        };
        MyFutureTask<Integer> myFutureTask = new MyFutureTask<>(myCallable);
        new Thread(myFutureTask).start();
        Integer result = myFutureTask.get();
        System.out.println("执行结果:" + result);
    }

}

九、HashTable、HashMap区别

1、HashTable:线程安全,通过synchroized保证 不允许Key null
2、HashMap:线程不安全,允许key null

十、ConcurrentHashMap简单实现:

1.7版本:底层使用分段锁设计,将一个大的HashTable线程安全的集合拆分成n多个小的HashTable集合,默认初始化16个小的HashTable集合,如果同时16个线程最终计算index值落在不同的小的HashTable集合,就不会发生锁的竞争,同时可以支持16个线程访问写的操作,效率非常高

import java.util.Hashtable;

public class MyConcurrentHashMap<K, V> {
    private final int DEFAULT_LENGT = 16;
    private Hashtable<K, V>[] hashtables;
    MyConcurrentHashMap(){
        hashtables = new Hashtable[DEFAULT_LENGT];
        for (int i = 0; i < hashtables.length; i++){
            hashtables[i] = new Hashtable<>();
        }
    }

    public void put(K k, V v) {
        int index = k.hashCode() % hashtables.length;
        hashtables[index].put(k, v);
    }

    public V get(K k) {
        int index = k.hashCode() % hashtables.length;
        return hashtables[index].get(k);
    }

    public static void main(String[] args) {
        MyConcurrentHashMap<String, String> hashMap = new MyConcurrentHashMap<>();
        hashMap.put("name", "xiaoming");
        hashMap.put("age", "12");
        System.out.println(hashMap.get("name"));
    }
}

相关文章

  • android 多线程 — 线程的面试题和答案

    这里都是我从各个地方找来的资料,鸣谢: Java多线程干货系列—(一)Java多线程基础 JAVA多线程和并发基础...

  • 技术体系

    一,java核心 java基础,jvm,算法,多线程,设计模式 Java基础:java基础相关,全栈java基础 ...

  • Java多线程目录

    Java多线程目录 Java多线程1 线程基础Java多线程2 多个线程之间共享数据Java多线程3 原子性操作类...

  • Java基础

    Java基础 集合基础 集合框架 多线程基础 多线程框架 反射 代理 集合基础 ArrayList LinkedL...

  • java多线程相关

    (一) 基础篇 01.Java多线程系列--“基础篇”01之 基本概念 02.Java多线程系列--“基础篇”02...

  • Java多线程高级特性(JDK8)

    [TOC] 一、Java多线程 1.Java多线程基础知识 Java 给多线程编程提供了内置的支持。一条线程指的是...

  • Java多线程系列目录(共43篇)-转

    最近,在研究Java多线程的内容目录,将其内容逐步整理并发布。 (一) 基础篇 Java多线程系列--“基础篇”0...

  • Android中的多线程

    1. Java多线程基础 Java多线程,线程同步,线程通讯 2. Android常用线程 HandlerThre...

  • Java架构师阅读书单

    一、内功心法 Java基础: 《Java核心技术》《Java编程思想》《Effective Java》 多线程...

  • java学习路线

    javaSE java基础语法 java文件操作 java网络操作 java多线程 java数据库操作 java ...

网友评论

      本文标题:Java基础|多线程

      本文链接:https://www.haomeiwen.com/subject/iagpfdtx.html