基本线程机制

基本线程机制

@(并发)[java, 并发, Thinking in Java]

  1. 单个进程可以拥有多个并发执行的任务,其底层机制是切分CPU时间

1. 定义任务

  1. 实现Runnable接口并编写run()方法
  2. 线程调度器:Thread.yield():Java线程机制的一部分,可以将CPU从一个线程转移给另一个线程,但是是选择性

2. Thread类

Thread thread = new Thread(obj implements Runnable);
thread.start()方法为线程执行必须的初始化操作,然后调用run()方法。

3. 使用Executor

java.util.concurrent包的执行器(Executor)将管理Thread对象,执行任务。Executor允许管理异步任务的执行—-优选

ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(obj implement Runnable);
executor.shutdown();//防止新任务提交给Executor

FixedThreadPool: 一次性预先执行代价高昂的线程分配,即限制线程的数量。
CachedThreadPool: 在程序执行过程中通常会创建与所需数量相同的线程,然后在回收旧线程时停止创建新线程
SingleThreadExecutor:线程数量为1的FixedThreadPool,会序列化所有提交给它的任务

4. 从任务中返回值–实现Callable接口

Callable接口是一种具有类型参数的泛型,它的类型参数表示的是从call()中返回的值,并且必须用ExecutorService.submit()调用。submit()方法会产生Future对象。

class MyClass implements Callable<String>{
}

ExecutorService executor = Executors.newCachedThreadPool();
Future<String> result = executor.submit(new MyClass());

5. 休眠

Thread.sleep(10);

TimeUnit.MILLISECONDS.sleep(10); //建议

6. 优先级

线程的优先级将该线程的重要性传递给调度器。调度器倾向于让优先权最高的线程执行。但优先级不会导致死锁。
优先级需要在run()方法的开头部分设定。
JDK有10个优先级,但是它与多数操作系统不能映射的很好,所以只建议使用MAX_PRIORITY, NORM_PRIORITY, MIN_PRIORITY三个等级

7. 让步

Thread.yield(): 暗示可以出让CPU给其它线程,但是没有任何机制会保证它将会被采纳。

8. 后台(daemon)线程

☞在后台提供通用服务的线程,并且这些线程并不属于程序中不可或缺的那部分。所以当所有非后台线程结束时,程序也就终止了,同时会杀死进程中所有的后台线程。

8.1 设置后台标志

//线程启动**之前**调用setDaemon()方法,才能将它设置为后台线程。
Thread daemon = new Thread(obj implement Runnable);
daemon.setDaemon(true);
daemon.start();

8.2. 定制ThreadFactory

public class DaemonThreadFactory implements ThreadFactory{
    public Thread newThread(Runnable r){
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
}

public static void main(String[] args){
    ExecutorService executor = Executors.newCachedThreadPool(new DaemonThreadFactory());
    executor.execute(obj implements Runnable);
}

Daemon线程派生出的子线程默认也为Daemon

9. 编码的变体

9.1. 直接继承Thread

public class MyThread extends Thread{
}

9.2. 自管理的Runnable

public class SelfManaged implement Runnable{
    private Thread t = new Thread(this);
    public SelfManaged(){
        t.start();
    }

    public void run(){}

}
//该方法可能会访问到处于不稳定状态的对象。因为另一个任务可能会在构造器结束之前开始执行。

9.3. 匿名内部类

10. 术语

Thread类自身不执行任何操作,它只是驱动赋予它的任务

11. 加入一个线程

如果某个线程在另一个线程t上调用t.join(),此线程将被挂起,直到目标线程t结束才恢复(即t.isAlive()返回false)
join()方法可以带超时参数,这样如果目标线程在这段时间到期还没结束的话,join()方法返回。

12. 创建有响应的用户界面

13. 线程组 —-不成功的尝试

14. 捕获异常

问题:线程中不能捕获异常,一旦逃出任务的run()方法,就会向外传播到控制台。即使在main()方法中捕获也没用

package concurrency;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * ${DESCRIPTION}
 *
 * @author cinhori
 * @version 1.0
 * @since 2017-08-12 12:50
 */
public class CaptureUncaughtException {
    public static void main(String[] args){
        ExecutorService service = Executors.newCachedThreadPool(new HandlerThreadFactory());
        service.execute(new ExceptionThread2());

    }
}

class ExceptionThread2 implements Runnable{
    @Override
    public void run() {
        Thread thread = Thread.currentThread();
        System.out.println("run by " + thread.getName());
        System.out.println("exceptionHandler: " + thread.getUncaughtExceptionHandler());
        throw new RuntimeException();
    }
}

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("caught " + e.toString());
    }
}

class HandlerThreadFactory implements ThreadFactory{
    @Override
    public Thread newThread(Runnable r) {
        System.out.println(this + " creating new Thread");
        Thread thread = new Thread(r);
        System.out.println("creating " + thread);
        thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
        System.out.println("ExceptionHandler: " + thread.getUncaughtExceptionHandler());
        return thread;
    }
}

设置默认的未处理捕获异常处理器:

public class SettingDefaultHandler{
    public static void main(String[] args){
        Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
        ExecutorService service = Executors.newCachedThreadPool();
        service.execute(new ExceptionThread());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值