线程
线程的创建有三种方式:
1.extends Thread,重写run()方法,在用start()启动。
2.implements Runnableable接口,同样重写run()方法。但区别在于runnable是可运行但不是一个线程,所以仍需要new Thread(实现接口的对象),作为参数传入。
代码如下:
private Runnable target; public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); } @Override public void run() { if (target != null) { target.run(); } }
3.匿名类Thread t=new Thread(){重写run和上面相同},好处在于可以访问外部的局部变量。//new Thread(){run..}.start()直接启动
//
//
线程的主要方法:
1.sleep,作用范围和break的作用有点类似。
2.join,可以认为是插队,运行完这个join的再继续上级线程。
3.优先级:
继承:一个线程中创建并运行了另一个线程,两者优先级一致,并且生命周期相互独立
规则:高优先级拥有的资源多
随机性:多资源并不保证一定先完成
//优先级并不是反映在时间上而是在资源的配置上,可以通过实验验证这点
4,守护线程,构造函数中设置True或setter:setDaemon(true);//日志相关功能,生命周期与父线程不独立//进程分为守护进程和用户进程
//
//
线程同步:在方法前加上synchronized修饰符,将this作为同步对象。所有方法前均有其修饰,则为线程安全的类,同一时间仅有一个线程能修改这个实例的数据。
//
线程安全带来的集合方法差异:
HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式
区别1:
HashMap可以存放 null
Hashtable不能存放null
区别2:
HashMap不是线程安全的类
Hashtable是线程安全的类
//
StringBuffer 是线程安全的
StringBuilder 是非线程安全的
所以当进行大量字符串拼接操作的时候,如果是单线程就用StringBuilder会更快些,如果是多线程,就需要用StringBuffer 保证数据的安全性
//
Vector是线程安全的类,而ArrayList是非线程安全的。
利用工具类collection中的方法可转换为线程安全的
//List<Integer> list2 = Collections.synchronizedList(list1);
//多线程之间会发生死锁
//
//
线程的交互方法:
//方法实际上是同步对象的方法,不是线程方法,因而前提为线程同步
wait(): 让占用了这个同步对象的线程,临时释放当前的占用,并且等待。 所以调用wait是有前提条件的,一定是在synchronized块里,否则就会出错。
notify(),通知一个等待在这个同步对象上的线程,你可以苏醒过来了,有机会重新占用当前对象了。
notifyAll(),通知所有的等待在这个同步对象上的线程,你们可以苏醒过来了,有机会重新占用当前对象了。
例:

浙公网安备 33010602011771号