码迷,mamicode.com
首页 > 编程语言 > 详细

JAVA thread

时间:2019-09-16 14:43:52      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:demo   notifyall   resource   ble   except   恢复   rgs   结束   实现   

摘要:JAVA thread


并行性
产生Thread的方法
方法一: 继承Thread类
1. 子类覆写父类中的run方法,将线程运行动作放在run函数中。
2. 建立子类对象的同时,线程也被创建
3. 使用start方法启动线程


class Demo extends Thread{
    public void run(){
                for(int x = 0; x < 60; x++){
                        System.out.println("Demo Run " + x);
                }
        }
}

class Test{
    public static void main(String args[]){
                Demo mDemo = new Demo();
                mDemo.start();
               
                for(int x = 0; x < 60; x++){
                        System.out.println("Main Function " + x);
                }
        }
}


方法二: 实践Runnable界面
1. 子类覆写界面中的run方法
2. 通过Thread类创建线程,并将实现了 Runnable界面的子类对象作为参数传递给 Thread类的构造函数
3. Thread类对象调用start方法开启线程。
思考:为什么要给Thread类的构造函数传递 Runnable的子类对象?



安全问题:
多线程下共享资源时,需注意互斥问题。利用同步来解决

问题:

class Hello{
    public static void main(String[] args){
        Resource r = new Resource();
        Input in = new Input(r);
        Output out = new Output(r);
        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        t1.start();
        t2.start();
    }
}


class Resource{
    String name;
    int sex;
}
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r = r;
    }
    public void run(){
        int x = 0;
        while(true){
            if(x == 0){
                r.name = "A";
                r.sex = 0;
            }else{
                r.name = "B";
                r.sex = 1;             
            }
            x = (x + 1)%2;
        }
    }
}
class Output implements Runnable{
    Resource r = new Resource();
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            System.out.println(r.name + "..." + r.sex);
            //B...0, B...1, A...0, A...1 问题发生
        }
    }
}

解决 加入同步


class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r = r;
    }
    public void run(){
        int x = 0;
        while(true){
            synchronized(r){
                if(x == 0){
                    r.name = "A";
                    r.sex = 0;
                }else{
                    r.name = "B";
                    r.sex = 1;             
                }
                x = (x + 1)%2;
            }
        }
    }
}
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            synchronized (r) {
                System.out.println(r.name + "..." + r.sex);
            }
        }
    }
}
synchronized(对象)
{
需要同步的程序片段;
}

同步需要两个或者两个以上的线程,多个线程使用的是同一个锁,未满足这两个条件,不能称其为同步。


同步函数
public synchronized void Test(){
}
同步函数被static修饰后其共用的锁就不是this,因为static不可用this
可使用该类对象,即类名称 .class 当锁

唤醒等待机制

class Resource{
    String name;
    int sex;
    boolean flag = false;
}
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r = r;
    }
    public void run(){
        int x = 0;
        while(true){
            synchronized(r){
                if(r.flag)
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                if(x == 0){
                    r.name = "A";
                    r.sex = 0;
                }else{
                    r.name = "B";
                    r.sex = 1;             
                }
                x = (x + 1)%2;
                r.flag = true;
                r.notify();
            }
        }
    }
}
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            synchronized (r) {
                if(!r.flag){
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(r.name + "..." + r.sex);
                r.flag = false;
                r.notify();
            }
        }
    }
}
wait(), notity(), notifyAll()
都使用在同步中,因为要对持有监视器的线程操作,所以要使用在同步中,因为只有同步才具有锁

修改

class Hello{
    public static void main(String[] args){
        Resource r = new Resource();
        new Thread(new Input(r)).start();
        new Thread(new Output(r)).start();
    }
}


class Resource{
    private String name;
    private int sex;
    private boolean flag = false;
   
    public synchronized void set(String name, int sex){
        if(flag){
            try{this.wait();}catch(Exception e){}
        }
        this.name = name;
        this.sex = sex;
        flag = true;
        this.notify();
    }
    public synchronized void out(){
        if(!flag){
            try{this.wait();}catch(Exception e){}
        }
        System.out.println(name + "..." + sex);
        flag = false;
        this.notify();     
    }
}
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r = r;
    }
    public void run(){
        int x = 0;
        while(true){
            if(x == 0){
                r.set("A", 0);
            }else{
                r.set("B", 1);             
            }
            x = (x + 1)%2;
        }
    }
}
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            r.out();
        }
    }
}

修正 多生产者及多消费者时,产生的异步错误,使用notifyAll()
while判断可以让被唤醒的thread再一次判断标记,使用notify()容易出现只唤醒本方thread,导致进程中的所以thread都变成等待,因为本方会因flag而卡住,故使用notifyAll()

class Hello{
    public static void main(String[] args){
        Resource r = new Resource();
        Producer pro = new Producer(r);
        Consumer con = new Consumer(r);
        Thread t1 = new Thread(pro);
        Thread t2 = new Thread(pro);
        Thread t3 = new Thread(con);
        Thread t4 = new Thread(con);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

class Resource{
    private String name;
    private int count = 1;
    private boolean flag = false;
   
    public synchronized void set(String name){
        while(flag){
            try{this.wait();}catch(Exception e){}
        }
        this.name = name + "--" + count++;
        System.out.println(Thread.currentThread().getName() + "---生产者---" + this.name);
        flag = true;
        this.notifyAll();
    }
    public synchronized void out(){
        while(!flag){
            try{this.wait();}catch(Exception e){}
        }
        System.out.println(Thread.currentThread().getName() + "消费者" + this.name);
        flag = false;
        this.notifyAll();      
    }
}


class Producer implements Runnable{
    private Resource res;
    Producer(Resource res){
        this.res = res;
    }
    public void run(){
        int x = 0;
        while(true){
            res.set("+A+");
        }
    }
}
class Consumer implements Runnable{
    Resource res;
    Consumer(Resource res){
        this.res = res;
    }
    public void run(){
        while(true){
            res.out();
        }
    }
}

2. 使用interrupt中断方法。该方法是结束线程的冻结状态,使线程回到运行状态
setPriority(int num)
setDaemon(boolean b)
join()
自订线程名称
toString()

Lock界面
Lock 实践提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作

使用Lock修改

class Hello{
    public static void main(String[] args){
        Resource r = new Resource();
        Producer pro = new Producer(r);
        Consumer con = new Consumer(r);
        Thread t1 = new Thread(pro);
        Thread t2 = new Thread(pro);
        Thread t3 = new Thread(con);
        Thread t4 = new Thread(con);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

class Resource{
    private String name;
    private int count = 1;
    private boolean flag = false;
    private Lock lock   = new ReentrantLock();
    private Condition condition = lock.newCondition();
    public void set(String name) throws InterruptedException{
        lock.lock();
        try{
            while(flag){
                condition.await();
            }
            this.name = name + "--" + count++;
            System.out.println(Thread.currentThread().getName() + "---生产者---" + this.name);
            flag = true;
            condition.signalAll();
        }finally{
            lock.unlock();//一定要关闭资源
        }
    }
    public void out() throws InterruptedException{
        lock.lock();
        try{
            while(!flag){
                condition.await();
            }
            System.out.println(Thread.currentThread().getName() + "消费者" + this.name);
            flag = false;
            condition.signalAll();
        }finally{
            lock.unlock();
        }
    }
}

class Producer implements Runnable{
    private Resource res;
    Producer(Resource res){
        this.res = res;
    }
    public void run(){
        int x = 0;
        while(true){
            try {
                res.set("+A+");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Consumer implements Runnable{
    Resource res;
    Consumer(Resource res){
        this.res = res;
    }
    public void run(){
        while(true){
            try {
                res.out();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

控制Thread
当没有指定的方式让冻结的tread恢复到运行状态,这时需要对冻结进行清除
强制让tread恢复到运行状态中来,这样就可以让thread结束
利用Thread类提供的interrupt();方法
//stop方法已经过时
//停止thread要使用run方法结束
//需控制循环结构让run方法结束

class Hello{
    public static void main(String[] args){
        StopThread st = new StopThread();
        Thread t1 = new Thread(st);
        Thread t2 = new Thread(st);
       
        t1.start();
        t2.start();
        int num = 0;
        while(true){
            if(num++ == 60){
                //st.changeFlag();
                t1.interrupt();
                t2.interrupt();
                break;
            }
            System.out.println(Thread.currentThread().getName() + ".....num");
        }
        System.out.println("over");
    }
}

class StopThread implements Runnable{
    private boolean flag = true;
    public synchronized void run(){
        while(flag){
            try{
                wait();//wait后 其他thread就可以进入此 synchronized 方法
            }catch(InterruptedException e){
                System.out.println(Thread.currentThread().getName() + ".....Excetpion");
                flag =false;
            }
            System.out.println(Thread.currentThread().getName() + ".....run");
        }
    }
    public void changeFlag(){
        flag = false;
    }
}

setDaemon()当主线程结束后,也会让调用此方法的线程结束
将该线程标记为守护线程或使用者线程

class Hello{
    public static void main(String[] args){
        StopThread st = new StopThread();
        Thread t1 = new Thread(st);
        Thread t2 = new Thread(st);
       
        t1.setDaemon(true);
        t2.setDaemon(true);
        t1.start();
        t2.start();
        int num = 0;
        while(true){
            if(num++ == 60){
                //st.changeFlag();
                t1.interrupt();
                t2.interrupt();
                break;
            }
            System.out.println(Thread.currentThread().getName() + ".....num");
        }
        System.out.println("over");
    }
}

class StopThread implements Runnable{
    private boolean flag = true;
    public synchronized void run(){
        while(flag){
            try{
                wait();
            }catch(InterruptedException e){
                System.out.println(Thread.currentThread().getName() + ".....Excetpion");
                flag =false;
            }
            System.out.println(Thread.currentThread().getName() + ".....run");
        }
    }
    public void changeFlag(){
        flag = false;
    }
}

join()

当a线程执行到了b线程的join()方法时,a就会等待,等b线程执行完,a才会执行


class Hello{
    public static void main(String[] args) throws InterruptedException{
        Demo st = new Demo();
        Thread t1 = new Thread(st);
        Thread t2 = new Thread(st);
       
        t1.start();
        t1.join();//t1向cpu抢夺执行权 做完才给主线程
        t2.start();
        for(int x = 0; x <5; x++){
            System.out.println("main ..." + x);
        }
        System.out.println("over");
    }
}

class Demo implements Runnable{
    public void run(){
        for(int x = 0; x <5; x++){
            System.out.println(Thread.currentThread().getName() + "..." + x);
        }
    }
}
执行结果:
-----------------------------------------

Thread-0...0
Thread-0...1
Thread-0...2
Thread-0...3
Thread-0...4
main ...0
main ...1
main ...2
main ...3
main ...4
over
Thread-1...0
Thread-1...1
Thread-1...2
Thread-1...3
-----------------------------------------?



//setPriority();、toString();
class Hello{
    public static void main(String[] args) throws InterruptedException{
        Demo st = new Demo();
        Thread t1 = new Thread(st);
        Thread t2 = new Thread(st);
       
        t1.start();
        t1.setPriority(Thread.MAX_PRIORITY);//10
        t2.start();
        for(int x = 0; x <80; x++){
            System.out.println("main ..." + x);
        }
        System.out.println("over");
    }
}

class Demo implements Runnable{
    public void run(){
        for(int x = 0; x <70; x++){
            System.out.println(Thread.currentThread().toString() + "..." + x);.
        }
    }
}


//yeild();
class Hello{
    public static void main(String[] args) throws InterruptedException{
        Demo st = new Demo();
        Thread t1 = new Thread(st);
        Thread t2 = new Thread(st);
       
        t1.start();
        t2.start();
        for(int x = 0; x <80; x++){
            System.out.println("main ..." + x);
        }
        System.out.println("over");
    }
}

class Demo implements Runnable{
    public void run(){
        for(int x = 0; x <70; x++){
            System.out.println(Thread.currentThread().toString() + "..." + x);
            Thread.yield();//暂停当前正在执行的线程对象,并执行其他线程。
        }
    }
}

使用封装方法产生线程去执行特定方法,提高并行性


class Hello{
    public static void main(String[] args) throws InterruptedException{
        new Thread(){
            public void run(){
                for(int x = 0; x < 100; x++){
                    System.out.println(Thread.currentThread().getName() + "..." + x);
                }
            }
        }.start();
        for(int x = 0; x < 100; x++){
            System.out.println(Thread.currentThread().getName() + "..." + x);
        }
       
        Runnable r = new Runnable(){
            public void run(){
                for(int x = 0; x < 100; x++){
                    System.out.println(Thread.currentThread().getName() + "..." + x);
                }
            }
        };
        new Thread(r).start();
    }
}









原文:大专栏  JAVA thread


JAVA thread

标签:demo   notifyall   resource   ble   except   恢复   rgs   结束   实现   

原文地址:https://www.cnblogs.com/petewell/p/11526599.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!