------- android培训、java培训、期待与您交流! ----------
-
Lock()实现提供了比使用synchronized方法和语句可获得更广泛的锁定操作。
-
private Lock lock =new ReentrantLock();
-
被锁的代码要用 lock.lock() lock.unlock() 包括。其中用try 。。。finally包围
-
同步:效率低,如果出现同步嵌套,会出现死锁。 但是安全。
-
死锁问题:两个或者两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象
-
线程间通信,不同种类的线程针对同一资源的操作。
-
多线程还可能出现同一个数据出现多次,或者输出不匹配问题。都属于线程安全问题。
-
等待 唤醒机制
-

-
Object类中wait()等待 notify()唤醒单个线程 notifyAll()唤醒所有线程
-
这些方法调用必须通过锁对象调用,二我们刚才使用的锁对象是任意锁对象。
wait()要用try catch包围 用唤醒notify()来解决死锁即一个run()里判断一个条件,如果成立就锁调用wait(),如果不成立,锁的判断条件改变,然后调用notify()唤醒。
-
运行状态图:

-
线程组:默认情况下是main线程组
getThreadGroup()获得线程组
Thread.currentThread().getThreadGroup().getName();返回线程组的名字。 -
改变线程组
首先创建一个线程组:ThreadGroup tg=new ThreadGroup("这是一个新的线程组");然后Thread t1=new Thread(tg,Myrunnale,"线程名");
-
通过线程组名称设置后台线程,tg.setDaemon() 设置守护线程。等等
线程组主要是对线程统一管理。
-
同步还可以在类里,把相应的方法设置成synchronized 注意方法里面的锁的对象是this
-
线程池:程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互,二使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存周期很短的线程时,更应该考虑使用线程池。
-
线程池每个线程结束后不会销毁,而是回到线程池变成空闲状态。
-
static ExecutorServicenewCachedThreadPool()
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。 -
static ExecutorServicenewFixedThreadPool(int nThreads)
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。 -
static ExecutorServicenewSingleThreadExecutor()
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。 -
A:创建一个线程池对象,控制要创建几个线程对象
ExecutorServoce newFixedThreadPool(int nThread)
B:这种线程池的线程可以执行:
可以执行Runnable对象或者CallAble对象代表的线程
做一个实现Runnable接口
C:调用如下方法即可:
Future<?> submit(Runnable task)
<T> Future<T> submit(Callable<T> task) -
newFixedThreadPool静态函数,直接调用
-
1 ExecutorService pool=Executors.newFixedThreadPool(2); 2 pool.submit(new MyRunnable);
- 结束线程池:pool.shutdown();
- 创建多线程方式3:
Callable是个接口 这个线程有返回接口,但是runnable没有返回结果。 跟 Runnable用法相似
他是通过线程池来创建线程。 这个不常见 - Future 表示submit异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。 麻烦,一般不用。
- 匿名内部类使用多线程“
1 //集成Thread类来实现多线程 2 new Thread(){ 3 public void run() { 4 for (int i = 0; i < 100; i++) { 5 System.out.println(Thread.currentThread().getName()+":"+i); 6 } 7 }; 8 }.start(); 9 //用Runnable接口实现 10 new Thread(new Runnable() { 11 12 @Override 13 public void run() { 14 // TODO Auto-generated method stub 15 for (int i = 0; i < 100; i++) { 16 System.out.println(Thread.currentThread().getName()+":"+i); 17 } 18 } 19 }){}.start(); - 但是对于,走的是子类的,即会输出world,不会输出hello
1 new Thread(new Runnable() { 2 3 @Override 4 public void run() { 5 // TODO Auto-generated method stub 6 for (int i = 0; i < 100; i++) { 7 System.out.println("hello"+":"+i); 8 } 9 } 10 }){ 11 public void run() { 12 for (int i = 0; i < 100; i++) { 13 System.out.println("world"+":"+i); 14 } 15 }; 16 }.start(); -
定时器:在指定时间做某件事或者重复某件事
Timer 一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。
- 依赖Timer和TimerTask两个类
Timer 定时
TimerTask :任务 -
构造方法摘要 Timer()
创建一个新计时器。 -
timer方法
cancel()
终止此计时器,丢弃所有当前已安排的任务。intpurge()
从此计时器的任务队列中移除所有已取消的任务。voidschedule(TimerTask task, Date time)
安排在指定的时间执行指定的任务。voidschedule(TimerTask task, Date firstTime, long period)
安排指定的任务在指定的时间开始进行重复的固定延迟执行。voidschedule(TimerTask task, long delay)
安排在指定延迟后执行指定的任务。voidschedule(TimerTask task, long delay, long period)
安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。voidscheduleAtFixedRate(TimerTask task, Date firstTime, long period)
安排指定的任务在指定的时间开始进行重复的固定速率执行。voidscheduleAtFixedRate(TimerTask task, long delay, long period)
安排指定的任务在指定的延迟后开始进行重复的固定速率执行。 - 面试题
1:多线程有几种实现方案,分别是哪几种? 两种。 继承Thread类 实现Runnable接口 扩展一种:实现Callable接口。这个得和线程池结合。 2:同步有几种方式,分别是什么? 两种。 同步代码块 同步方法 3:启动一个线程是run()还是start()?它们的区别? start(); run():封装了被线程执行的代码,直接调用仅仅是普通方法的调用 start():启动线程,并由JVM自动调用run()方法 4:sleep()和wait()方法的区别 sleep():必须指时间;不释放锁。 wait():可以不指定时间,也可以指定时间;释放锁。 5:为什么wait(),notify(),notifyAll()等方法都定义在Object类中 因为这些方法的调用是依赖于锁对象的,而同步代码块的锁对象是任意锁。 而Object代码任意的对象,所以,定义在这里面。 6:线程的生命周期图 新建 -- 就绪 -- 运行 -- 死亡 新建 -- 就绪 -- 运行 -- 阻塞 -- 就绪 -- 运行 -- 死亡 建议:画图解释。
来源:https://www.cnblogs.com/PiaoYing-Java/p/4606060.html

