三种方式
继承Thread类,重写run()方法
实现Runnable接口,重写run()方法
实现Callable接口(指定返回值),重写call()方法,使用Future包装创建实例

继承Thread是最容易的,但是也是最不灵活的,并且不能共享任务
使用Callable时最复杂的,但是也是最灵活的
API
| 一些属性 | 使用 |
|---|---|
| 名字 | thread.setName() / thread.getName() |
| 是否是守护线程 | thread.setDaemon() / thread.isDaemon() |
| 线程优先级 | thread.setPriority(Thread.NORM_PRIORITY) |
| 所属线程组 | thread.getThreadGroup() |
| 线程组 | |
| 组中活的线程数 | threadGroup1.activeCount() |
| 中断组中所有线程 | threadGroup1.interrupt() |
| 设置线程最高优先级 | threadGroup1.setMaxPriority(10); |
一些理解: 上面提到的继承Thread写法不能共享,是因为创建和调用时每次都要new出一个新线程,而runnbale和callbaled的写法可以看出更把任务丢进Thread()这个线程中,所以实现了复用和任务共享。
比如下面这个例子:名为a1,a2的两个线程在执行时同时处理run方法
线程同步
当多个线程访问同一资源时,在不确定的时间,不确定是哪个线程先执行的情况下,会导致结果不稳定性。这时候就需要锁来进行线程同步,可以脑补上厕所排队,进去了锁门这个画面
一个是可以使用synchronized同步,一个是可以使用Lock。synchronized是也是隐式的锁。
锁方法
当多个线程调用同一个第一个对象的同步方法时会阻塞,而调用不同的对象时则不会。 这次再执行上面共享任务的例子会发现,因为a1排前头咔咔都给做完了,导致a2完全没出过,这也能更好的说明他俩确实是共享资源和任务的。
使用Lock锁
锁代码块
锁类
锁一个类的静态方法也算作锁类,那么问题来了我既锁了类,也锁了类的方法,那么分别执行后,他俩能同步数据吗?
答案是不会阻塞
总结
1,要满足方法同步(或者代码块同步)就必须保证多线程访问的是同一个对象(在java内存中的地址是否相同)。
2,类锁和对象锁同时存在时,多线程访问时不会阻塞,因为他们不是一个锁。


这里的this是指当前对象,当然也可以锁需要被修改的变量
