三种方式

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

创建线程的三种方式 - 图2

创建线程的三种方式 - 图3
继承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方法
创建线程的三种方式 - 图4
创建线程的三种方式 - 图5

线程同步

当多个线程访问同一资源时,在不确定的时间,不确定是哪个线程先执行的情况下,会导致结果不稳定性。这时候就需要锁来进行线程同步,可以脑补上厕所排队,进去了锁门这个画面
一个是可以使用synchronized同步,一个是可以使用Lock。synchronized是也是隐式的锁。

锁方法

创建线程的三种方式 - 图6当多个线程调用同一个第一个对象的同步方法时会阻塞,而调用不同的对象时则不会。 这次再执行上面共享任务的例子会发现,因为a1排前头咔咔都给做完了,导致a2完全没出过,这也能更好的说明他俩确实是共享资源和任务的。

使用Lock锁

创建线程的三种方式 - 图7
创建线程的三种方式 - 图8

锁代码块

创建线程的三种方式 - 图9这里的this是指当前对象,当然也可以锁需要被修改的变量

锁类

创建线程的三种方式 - 图10锁一个类的静态方法也算作锁类,那么问题来了我既锁了类,也锁了类的方法,那么分别执行后,他俩能同步数据吗?
答案是不会阻塞
总结
1,要满足方法同步(或者代码块同步)就必须保证多线程访问的是同一个对象(在java内存中的地址是否相同)。
2,类锁和对象锁同时存在时,多线程访问时不会阻塞,因为他们不是一个锁。