线程
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成神的系列文章之一
如果你想知道,但是本文没有的,请下方留言
我会第一时间总结出来并发布填充到本文