java并发编程基础 (2)

为啥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加在普通方法上,锁为当前实例对象

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzdsxd.html