如何保证线程安全
(1) 使用同步代码块
(2) 使用同步方法。
当多个线程访问一个对象时,如果不用进行额外的同步控制或其他的协调操作,调用这个对象的行为都可以获得正确的结果,我们就说这个对象是线程安全的
那么我们如何做到线程安全?
1,如果是多个线程访问同一个资源,那么就需要上锁,才能保证数据的安全性。
2. 如果每个线程访问的是各自的资源,那么就不需要考虑线程安全的问题,所以这个时候,我们可以放心使用非线程安全的对象,没有冲突
线程安全类:
(1) Hashtable (2) StringBuffer (3)Vector
Hashtable和hashmap得区别?
- 线程安全(hashtable线程安全 )
- key和value是否允许null(hashMap允许键和值为空值 hashtable是不允许的)
- 效率上(hashMap的效率会高与hashtable)
1.wait方法和sleep方法得区别?
(1)wait属于Object类,sleep属于Thread类
(2)wait会是否锁资源,sleep不会释放锁资源
(3)wait需要notify和notifyAll唤醒, sleep时间到了会自动唤醒。
(4)wait必须使用在同步代码块或者同步方法中, sleep可以在任何地方使用。
2.notify和notityAll得区别?
1.notify 随机唤醒等待队列中的某个线程,
2.notifyAll 唤醒等待队列中所有的线程。
public class Test {
public static void main(String[] args) {
//1.固定长度的线程池
// ExecutorService executorService = Executors.newFixedThreadPool(3);
//2.可变长度得线程池 如果存在空闲的线程,则不会创建新的。
//ExecutorService executorService = Executors.newCachedThreadPool();
//3. 创建单一线程池
//ExecutorService executorService = Executors.newSingleThreadExecutor();
//4. 创建定长延迟线程池。
// ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
// int corePoolSize, 核心池大小 执行的最大数
// int maximumPoolSize, 最大池数 执行+等待
// long keepAliveTime, 存活时间
// TimeUnit unit, 时间单位
// BlockingQueue<Runnable> workQueue
//5.ExcutorsService实现类创建.ThreadPoolExecutor
ArrayBlockingQueue blockingQueue=new ArrayBlockingQueue(2);
ExecutorService executorService=new ThreadPoolExecutor(3,5,30,TimeUnit.SECONDS,blockingQueue);
Runnable tast1=new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+"执行");
}
};
for(int i=0;i<8;i++) {
executorService.execute(tast1);
}
}
}
submit和execute区别?
submit可以提交runnable和callable类型的任务
而execute执行提交Runnable类型的任务
Callable实现线程的特点?
a.可以在任务结束后提供一个返回值,Runnable不行
b.call方法可以抛出异常,Runnable的run方法不行
c.可以通过运行Callable得到的Fulture对象监听目标线程调用call方法的结果,得到返回值,(fulture.get(),调用后会阻塞,直到获取到返回值)
Callable接口实现多线程的应用场景 :当父线程想要获取子线程的运行结果时.
- (1)Callable规定的方法是call(),而Runnable规定的方法是run().
- (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
- (3)call()方法可抛出异常,而run()方法是不能抛出异常的。
- (4)运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。
- 它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
- 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
- Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
sleep 和 wait 的区别
1,所属的类不同:
sleep方法是定义在Thread上(线程)
wait方法是定义在Object上(对象)
2,对于锁资源的处理方式不同
sleep不会释放锁
wait会释放锁
notify() 唤醒wait队列随机一个线程 喚醒nofityAll()wait队列中的全部线程
3,使用范围:
sleep可以使用在任何代码块
wait必须在同步方法或同步代码块执行
4,与wait配套使用的方法
notify() notifyAll()