package java.lang
线程创建
一共两种创建方法,一:
public class Thread {
private Runnable r;
public Thread(Runnable r){
this.r=r;
}
}
public interface Runnable(){
public void run(){
..
}
}
//下面是自己要实现的
class B implements Runnable{
public void run(){
..
}
}
Thread t1=new Thread(new B());
//实际上并不是start就是真的开始了,而是在线程调度程序中注册了一下
//什么时候运行我们无法控制,甚至顺序都可能改变
t1.start();
第二钟创建方法
public class MyThread extends Threads{
public void run();
}
//使用匿名类,匿名类没有构造函数
//但是可以加一对{}作为初始化函数
//怎样调用父类的构造函数呢?那个()就是那个意思了
Thread t1=new Thread(){
{
i=9;
}
public void run()[
}
};
t1.start();
//实现接口,
Thread t1=new Thread(new Runnable(){
{
i=9;
}
public void run()[
}
});
t1.start();
强行终止线程 t.stop();
挂起线程 t.suspend();
继续工作 t.resume();
线程状态:running,ready
Thread.sleep(1000);
这是静态函数,让运行到这行代码的那个程序停一下
Thread.yield();
也是静态,从running变成ready一下,让别的进程跑会
同步代码,使用synchronized对象锁,任何一个对象其实都有一个隐含的对象锁,通过锁来保护共享数据
lock不止可以加在对象上,也可以加在代码段上
public class TwoLock{
int i,j;
int x,y;
void a(){
//同步代码不要保护局部变量
int i1=5;
i1++;
synchronized(lock1){
//access i,j
}
void b(){
synchronized(lock1){
//access i,j
}
}
void c(){
synchronized(lock2){
//access x,y
}
void d(){
synchronized(lock2){
//access x,y
}
1.同步泄露 ,访问共享数据的代码有些加锁有的没加锁
2.共享数据往往是类的成员变量
3.但是对函数内的新的局部变量都是不需要加在锁内的
4.同步代码会使速度变慢,尽量少用
volatile
原子的操作,不可分割的
这个可以直接用来修饰共享数据,这样其他函数对它的操作一定是被保护的,但是只是对与简单的操作,比如就简单的读写操作才可以。复杂的函数volatile就没效果了,所以还是要用sync
synchronized public void push(char c){
while(index==data.length){
try{
wait();
//这里会释放它的所有资源
//也可以:
byte[] b=new byte[];
synchronized(b){
b.wait();
}
//我这里使用new byte[0].wait()不可以,因为wait和notify函数是定义在对象上的,我可以调用任何一个对象让它等待
//我这里直接使用new byte[0].wait()不可以,因为调用wait一定要持有这个对象的锁,而只有操作它时才能有它的锁!
}catch(InterruptedException){
e.printStackTrace();
}
}
data[index]=c;
index++;
notifyAll();
//或者使用notify(),是唤醒这个锁下的某一个线程,而notifyAll()是唤醒这个锁下的全部线程,线程会先争用CPU执行权,然后争用对象锁。我们应该都使用nootifyAll(),因为尽管效率会有点点低,但总不会**漏掉**线程。
}
synchronized public char pop(){
//不可以用if!一定要用while,因为if的话,可能在wait被唤醒的情况下,这个wait还没得到锁,别人得到锁做了更改,结果回来这个wait直接走下去了,不再回头判断了,结果就错了
if(index==0){
try{wait();}catch(Exception e){}
}
index--;
notifyAll();
return data[index];
}
其实上面的代码不好,因为wait的条件其实不一致,是两伙儿的
什么时候可以用notify()?
我们其实应该有两把锁,这样上面代码要改写很多(其实下面的代码是有死锁风险的,需要再有一个额外的flag去避免死锁)
java.util.concurrent
并发
重要类:LinkedBlockingQueue
public static LinkedBlockingQueue q=new();
Thread t1=new Thread(){
public void run(){
BufferedReader br=new BufferedReader(new InputStreamReader(System.in,"GBK");
String s=null;
while((s=br.readLine())!=null){
q.put(s);
}
}
};
Thread t2=new Thread(){
public void run(){
while(true){
System.out.println(q.get());
}
}
};