多线程
1.概念杂记
* runnable不叫线程,叫任务
* 继承和接口,一般优先选择接口
* 线程睡眠时会释放cpu
* 后台线程(守护线程)会因前台线程的结束而结束
* 线程优先级1-10,默认5
* 多线程同步机制必须使用同一把锁(即同一个对象)
* 同步方法使用的锁就是调用的对象this
* 多线程用StringBuffer,单线程用StringBuilder
* synchronized既能同步代码块,也能同步方法
* yield()是让出cpu,但是还可以再抢
* static synchronized的锁为类名.class(字节码文件)
* 单例模式安全性和效率解决方法:多重判断
* wait()等待,notify()唤醒
* wait()会释放锁,sleep不会释放锁
* wait()必须放在同步中
* 因为同步锁可以为任意锁或对象,所以wait方法在Object类下
* 同步嵌套同步,发生死锁的概率很大
* 哪个线程执行wait(),哪个线程就等待
2.线程两种启动方法
* 继承Thread类
class MyThread extends Thread{
@Override
public void run() {
XXX;
}
}
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start();
}
}
* 实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
XXX;
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread t1 = new Thread(runnable);
t1.start();
}
}
3.多线程
* 继承Thread类
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start();
t2.start();
* 实现Runnable接口
MyRunnable runnable = new MyRunnable();
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
t1.start();
t2.start();
4.线程安全较高效率的单例模式
public class SingleInstance {
private static SingleInstance single;
private SingleInstance(){}//构造方法私有化为了不让别人new
public static SingleInstance getInstance(){
if(single == null){
synchronized (SingleInstance.class) {
if(single == null){
single = new SingleInstance();
}
}
}
return single;
}
}
5.wait方法和sleep方法的区别
* 1:wait方法会释放锁,sleep方法不会释放锁。
* 2:wait必须放在同步中,sleep不一定放在同步中.
* 3:wait一般的情况是让对方唤醒。sleep通常会自己醒过来。
* 4:wait需要用锁去调用。sleep是用Thread类或者Thread对象来调用。
6.Condition
public static Lock lock = new ReentrantLock();
//创建一个Condition
public static Condition p_con = lock.newCondition();
public static Condition c_con = lock.newCondition();
例子:
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length)
putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length)
takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
7.Executors-线程池
ExecutorService service = Executors.newFixedThreadPool(2);
for(int i = 0;i<100;i++){
service.execute(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+i);
}
});
}
8.线程的生命周期