为啥Thread构造里边能放Runnable,也能放FutureTask? 其实FutureTask继承RunnableFuture,而RunnableFuture继承Runnable和Future,所以FutureTask也是Runnable
三种方式比较 方式 使用简易程度 是否可以共享任务代码 是否可以有返回值 是否可以声明抛出异常 是否可以再继承别的类继承Thread 简单 不能 不能 不能 不能
Runnable 中等 可以 不能 不能 可以
Callable 复杂 可以 可以 可以 可以
继承Thread是最容易的,但是也是最不灵活的
使用Callable时最复杂的,但是也是最灵活的
这里说的共享任务代码举个例子:
还是上面那个MyThreadByRunnable类
MyThreadByRunnable myThreadByRunnable = new MyThreadByRunnable(); Thread thread = new Thread(myThreadByRunnable); thread.start(); // 再来一个,复用了任务代码,继承Thread就不行 Thread thread2 = new Thread(myThreadByRunnable); thread2.start(); 线程的一些属性 名字给以给线程取一个响亮的名字,便于排查问题,默认为Thread-${一个数字}这个样子
设置名字
threadA.setName("欢迎关注微信公号'大雄和你一起学编程'");获取名字
threadA.getName(); 是否是守护线程(daemon)为其他线程服务的线程可以是守护线程,守护线程的特点是如果所有的前台线程死亡,则守护线程自动死亡。
非守护线程创建的线程默认为非守护线程,守护线程创建的则默认为守护
set
threadA.setDaemon(true);get
threadA.isDaemon(); 线程优先级(priority)优先级高的线程可以得到更多cpu资源, 级别是1-10,默认优先级和创建他的父线程相同,main是5
set threadA.setPriority(Thread.NORM_PRIORITY); get threadA.getPriority() 所属线程组可以把线程放到组里,一起管理
设置线程组Thread的构造里边可以指定
ThreadGroup threadGroup = new ThreadGroup("欢迎关注微信公号'大雄和你一起学编程'"); Thread thread = new Thread(threadGroup, () -> { System.out.println("欢迎关注微信公号'大雄和你一起学编程'"); }); 拿到线程组 thread.getThreadGroup() 基于线程组的操作 ThreadGroup threadGroup1 = thread.getThreadGroup(); System.out.println(threadGroup1.activeCount()); // 有多少活的线程 threadGroup1.interrupt(); // 中断组里所有线程 threadGroup1.setMaxPriority(10); // 设置线程最高优先级是多少 线程同步多个线程访问同一个资源可能会导致结果的不确定性,因此有时需要控制只有一个线程访问共享资源,此为线程同步。
一个是可以使用synchronized同步,一个是可以使用Lock。synchronized是也是隐式的锁。
同步方法 class Account { private Integer total; public Account(int total) { this.total = total; } public synchronized void draw(int money) { if (total >= money) { this.total = this.total - money; System.out.println(Thread.currentThread().getName() + "剩下" + this.total); } else { System.out.println(Thread.currentThread().getName() + "不够了"); } } public synchronized int getTotal() { return total; } } public class Demo_02_04_1_ThreadSync { public static void main(String[] args) { Account account = new Account(100); Runnable runnable = new Runnable() { @Override public void run() { while (account.getTotal() >= 10) { account.draw(10); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread A = new Thread(runnable); A.setName("A"); Thread B = new Thread(runnable); B.setName("B"); A.start(); B.start(); } }假设AB两个人从同一个账户里取钱,直接在draw这个方法加synchronized关键字,防止两个人同时进入draw
sychronized加在普通方法上,锁为当前实例对象