Java 多线程操作

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());
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值