java成神之——线程操作

线程

Future

Callable 将一段代码包装在另外一个线程中执行
Future   是处理Callable计算后的结果

ExecutorService es = Executors.newSingleThreadExecutor(); // 创建单一线程
Future<String> result = es.submit(new Callable<String>(){
    @Override
    public String call() throws Exception {
        Thread.sleep(10000);                              // 执行复杂代码块的线程停留10s
        return "Complex Result";
    }
});
System.out.println("Result of Complex Calculation is : " + result.get());  // get方法会阻塞当前线程,一直等待Callable执行结束
result.get(5, TimeUnit.SECONDS)) // 只会等待结果5s
result.cancel(true);             // 终止线程
result.isDone();                 // 线程是否结束
result.isCancelled();            // 线程是否取消

CountDownLatch

CountDownLatch 未执行的线程数

下面例子,演示如何等待5个线程依次执行完毕后,主线程才会执行
CountDownLatch latch = new CountDownLatch(5); 
for (int n = 0; n < 5; n++) {
    Thread t = new Thread(new Runnable(){
            
        @Override
        public void run() {
            System.out.println("Do some thing");
            latch.countDown();                        // 执行完成一个线程,latch减一
        }
    });
    t.start();
}
latch.await();                                        // 等待子线程执行完成 
System.out.println("主线程 " + 5 + "threads");

Multithreading

for (int i = 1; i <= 4; i++) {
    new Thread(new Runnable(){
            
        @Override
        public void run() {
            for (int i = 0; i < 10000; i++) {
                System.out.println("Instance : " + i);
            }
        }
    }).start();
}

for (int i = 0; i < 10000; i++) {
    System.out.println("Main: " + i);
}

synchronized

控制单一线程访问资源

第一种
    int count = 0;
    public void doSomething() {
        synchronized(this) {
            ++count;
        }
    }

第二种
    Lock lockObj = new ReentrantLock()
    lockObj.lock();
    ++count;
    lockObj.unlock()

第三种
    Lock lockObj = new ReentrantLock();
    try {
        try {
            lockObj.lockInterruptibly();
            ++count;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // stopping
        }
    } finally {
        if (!Thread.currentThread().isInterrupted()) {
            lockObj.unlock(); 
        }
    }

第四种
    Lock lockObj = new ReentrantLock();
    boolean locked = lockObj.tryLock();
    if (locked) {
        try {
            ++count; 
        } finally {
            lockObj.unlock(); 
        }
    }

第五种
    Semaphore 可以指定具体的允许连接数

    Semaphore semaphore = new Semaphore(1);         // 最多1个连接
    Semaphore semaphore = new Semaphore(1, true);   // 按顺序处理连接
    semaphore.acquire();
    ++count; 
    semaphore.release();

第六种
    ReadWriteLock RW_LOCK = new ReentrantReadWriteLock();
    RW_LOCK.writeLock().lock();
    ++count; 
    RW_LOCK.writeLock().unlock();

    RW_LOCK.readLock().lock();
    return data;
    RW_LOCK.readLock().unlock();

Thread

创建线程

第一种
    class MyThread extends Thread {

        public MyThread(String name) {
            super(name); // 设置线程名称
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("Thread running!");
            }
        }

    }
    MyThread t = new MyThread("MyThreadName"); // 线程开启

第二种
    Thread t = new Thread(new Runnable(){
            
        @Override
        public void run() {
                    
        }
    });

第三种
    ThreadFactory threadfactory = new ThreadFactory(){

        private int id = 0;

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "Worker " + id++);
        }
    };
    threadfactory.newThread(...)

Producer-Consumer

BlockingQueue<Object> queue = new ArrayBlockingQueue<Object>(1000);
Runnable Producer = new Runnable(){
    @Override
    public void run() {
        int producedCount = 0;
        try {
            while (true) {
                producedCount++;
                queue.put(new Object());
            }
        } catch (InterruptedException e) {
            producedCount--;
            Thread.currentThread().interrupt();
        }
        System.out.println("Produced " + producedCount + " objects");
    }
};

Runnable Consumer = new Runnable(){
    @Override
    public void run() {
        int consumedCount = 0;
        try {
            while (true) {
                Object data = queue.poll(10, TimeUnit.MILLISECONDS);
                // process data
                consumedCount++;
            }
        } catch (InterruptedException e) {
            consumedCount--;
            Thread.currentThread().interrupt();
        }
        System.out.println("Consumed " + consumedCount + " objects");           
    }
};
Thread producer = new Thread(Producer);
Thread consumer = new Thread(Consumer);

producer.start();
consumer.start();

Thread.sleep(1000);
producer.interrupt();
Thread.sleep(10);
consumer.interrupt();

获取线程状态

Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread t : threadSet) {
    if (t.getThreadGroup() == Thread.currentThread().getThreadGroup()) {
        System.out.println("Thread :" + t + ":" + "state:" + t.getState());
        ++threadCount;
    }
}

线程池

ThreadPoolExecutor
    ThreadPoolExecutor pool = new ThreadPoolExecutor(
        1,                  // 保持一个线程一直存在
        5,                  // 最多5个线程一起执行
        1,                  // 最大空余的线程
        TimeUnit.MINUTES,   // 一分钟后终止空余线程
        new ArrayBlockingQueue<Runnable>(10) // Runnables实例保存在此
    )

    pool.execute(new Runnable() {
        @Override public void run() {
            //code to run
        }
    });

Executors

    ExecutorService es = Executors.newFixedThreadPool(2);
    es.submit(
        new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < 100; i++) {
                    System.out.println("子线程->" + i);
                }
            }
        }
    );

ThreadLocal

线程变量,只能在本线程中使用

创建线程变量
Thread thread = new Thread(new Runnable(){
    ThreadLocal<String> str = new ThreadLocal<String>(){
        @Override
        protected String initialValue() {
            return "线程变量";
        }
    };
    // 简写 ThreadLocal<String> str = ThreadLocal.withInitial(() -> "线程变量");

    @Override
    public void run() {
        System.out.println(str.get()); // "线程变量"
        str.set("修改的线程变量");
        System.out.println(str.get()); // "修改的线程变量"
    }
});
thread.start();

原子类型

避免多线程占用,线程安全

AtomicInteger aInt = new AtomicInteger();
AtomicInteger aInt = new AtomicInteger(1);
AtomicIntegerArray aIntArray = new AtomicIntegerArray(10);
AtomicIntegerArray aIntArray = new AtomicIntegerArray(new int[] {1, 2, 3});

结语

本文章是java成神的系列文章之一

如果你想知道,但是本文没有的,请下方留言

我会第一时间总结出来并发布填充到本文
原文地址:https://www.cnblogs.com/ye-hcj/p/9750432.html