Java多线程

前提是你 提交于 2020-11-24 06:27:06

1. 基本的线程机制

实现Runnable接口,编写run()方法。

将Runnable对象提交给Thread构造器,start()方法来启动线程。

Thread.yield()静态方法:当前线程进入“就绪状态”,同等优先级的等待线程可以获取执行权,但不保证线程调度一定发生。

使用java.util.concurrent包中的Executor管理Thread对象。

ExecutorService exec = Executors.newCachedThreadPool();
ExecutorService exec = Executors.newFixedThreadPool(5); //固定线程数量
ExecutorService exec = Executors.newSingleThreadExecutor(); exec.execute(new Task());
exec.shutdown()

SingleThreadExecutor使用场景:监听进入套接字链接的任务

shutdown()方法的调用可以防止新任务提交给Executor,shutdown()被调用之前的任务会被继续执行。

当任务中产生返回值时,实现Callable接口的call()方法

class TaskWithResult implements Callable<String> {
    public String call() {
        return "HelloWorld";
    }
}

ExecutorService exec = Executors.newCachedThreadPool();
Future<String> result = exec.submit(new TaskWithResult());

System.out.println(result.get());   //输出返回值 

线程休眠

Thread.sleep(100);
TimeUnit.MILLISECONDS.sleep(100);

线程优先级

thread.setPriority(Thread.MIN_PRIORITY);
thread.setPriority(Thread.NORM_PRIORITY); thread.setPriority(Thread.MAX_PRIORITY);

后台线程、守护线程

thread.setDaemon(true);

捕获异常

不能捕获从线程中逃逸的异常,一旦异常逃出run()方法,就会向外传播到控制台

class ExceptionTask implements Runnable {
    public void run() {
        throw new RuntimeException();
    }
}

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println(e);
    }
}

class HandlerThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setUncaughtExceptionHandler( new MyUncaughtExceptionHandler());
        return t;
    }
}

ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
execc.execute(new ExceptionTask());

2. 并发程序中的资源共享

synchronized关键字

java.util.concurrent.locks.*

Lock lock = new ReentrantLock();
lock.lock();
try {
  return;
} finally {
    lock.unlock();
}
Lock lock = new ReentrantLock();
boolean captured = lock.tryLock();
boolean captured = lock.tryLock(2, TimeUnit.SECONDS);
try {
    System.out.println("tryLock(): " + captured);
} finally {
    if(captured)
    lock.unlock(); }

原子操作:不被线程调度机制中断的操作

原子类:AtomicInteger, AtomicLong, AtomicReference,他们提供了原子性条件更新操作

boolean comareAndSet(exceptedValue, updateValue)
class AtomicIntegerTask implements Runnable {
    private AtomicInteger i = new AtomicInteger(0);
    public int getValue() { return i.get(); }
    private void increase() { i.addAndGet(2); }
    public void run() {
        increse();
    }
}

通过AtomicIntegerTask创建线程时,可以消除synchronized关键字。

3. 线程间的协作

Object的wait()和notify()、notifyAll()方法。

wait():该线程的执行被挂起,对象上的锁被释放。直到线程接收到notify()或者notifyAll()的消息,重新获得锁后,继续执行。

只能在同步方法或者同步代码块中调用上述三个方法

Lock lock = new ReentrantLock();
Condition confition = lock.newCondition();
lock.lock()
try {
    condition.await();
    condition.signal();
    condition.signalAll();
} finally {
    lock.unlock();
}

也可以使用java.util.concurrent类库中的Condition

同步队列:实现java.util.concurrent.BlockingQueue接口的队列包括:LinkedBlockingQueue(无界队列), ArrayBlockingQueue(固定尺寸), SynchronousQueue(固定尺寸为1).

多线程下,任务间使用管道进行输入/输出控制。

4 新类库中的构件

 CountDownLatch 实现类似计数器的功能

public CountDownLatch(int count) {  };  //参数count为计数值
public void await() throws InterruptedException { };   //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { };  //将count值减1

CyclicBarrie:创建一组并行执行的任务,等到所有任务都完成后再进行下一个步骤。所有并行任务都将在栅栏处列队。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!