Java 多线程操作

来源:互联网 发布:有哪些域名交易网站 编辑:程序博客网 时间:2024/06/07 08:59

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());        }    }};
原创粉丝点击