实现线程基本方式:
1)继承Thread类,覆盖run方法,new实例调用start()方法。
如:public MyThread extends Thread{
public void run(){
........
}
}
。。main(。。){
MyThread t=new MyThread();
t.start();
}
2)实现Runnable接口,覆盖run方法,new实例传给thread线程
如:public MyRunnable implements Runnable{
public void run(){
........
}
}
。。main(。。){
MyRunnable r=new MyRunnable();
Thread t=new Thread(r);
t.start();
}
选择方式,根据是否已经继承,没有继承则两种都可,继承了只能选择实现接口方式
多线程:
多线程同享数据:1.用类模板 2.只new一个对象
锁:是对象锁,要为Object类型,不能为基本数据类型,但是可声明一个与基本数据类型的平行对象。
如: public static int num=200;
public static Object obj=new Object();
如果将num作为锁,则可用obj代替num,因为obj和num在同一模板上。
如果对象锁是非静态的,则可以直接用this代替。注意,对象锁一定要是同一个对象才能锁起来
public class TicketWin implements Runnable {
private String win;
public TicketWin(String win) {
this.win = win;
} //基本数据类型无法当作对象锁,那么可以创建一个平行对象来代替它
private static int num=200;//共享数据
private static Object obj=new Object();
//锁---对象锁 obj
@Override
public void run() {
while (true) {
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj) {//拿锁/抢锁 ---用平行对象obj代替num当锁
if (num > 0) {
System.out.println(win+num);
num--;
} else {
break;
}
}//还锁
}
}
}
只能new一个对象:
public class Demo {
public static void main(String[] args) {
TicketWin w = new TicketWin();
Thread t1 = new Thread( w );
Thread t2 = new Thread( w );
t1.start();
t2.start();
}
}
进程调度:
1.优先级:setpriority()优先级为相对调度,也就是说优先级高不一定代码可以先执行,只是概率高些,范围0到10,默认5
2.sleep():抢到线程如果进入sleep则不会释放锁
3.interrupt()
4.yeild(),必须是优先级相同的线程才能调度,主动让出一次机会给同一优先级的线程
5.join(),把该线程并入到当前抢到时间片的线程且先运行,属于绝对调度,一定先执行完
6.wait():抢到线程如果进入wait则会释放锁
7.notify():随机唤醒等待池中一个wait()线程
8.notifyAll(),唤醒等待池中所有的wait()线程
避免死锁原则:
1.在同步块中不要写阻塞方法。
2.同步块中代码越少越好。
3.在持有锁的时候,不要调用其他对象方法。