Java多线程入门2

三世轮回 提交于 2021-01-13 00:33:35

线程死锁简单示例

package second.study;

public class Test {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new DeadLock(true));
        Thread thread2 = new Thread(new DeadLock(false));
        thread1.start();
        thread2.start();
    }
}

class DeadLock implements Runnable {

    private boolean flag;

    DeadLock(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if (flag) {
            while (true) {
                synchronized (Lock.obj1) {
                    System.out.println("if Lock1");
                    synchronized (Lock.obj2) {
                        System.out.println("if Lock2");
                    }
                }
            }
        } else {
            while (true) {
                synchronized (Lock.obj2) {
                    System.out.println("else Lock2");
                    synchronized (Lock.obj1) {
                        System.out.println("else Lock1");
                    }
                }
            }
        }

    }
}

class Lock {
    static Object obj1 = new Object();
    static Object obj2 = new Object();
}

多线程间通信

  解决线程间通信的安全问题的关键是,在操作共享数据时使用同一把锁将共享数据进行锁定!这样,别的线程就算获得了cpu的执行权,没有锁也无法运行共享数据。

  wait(); notify(); notifyAll();都使用在同步中,因为要对持有监视器(锁)的线程进行操作。只有锁对象内才具有wait()等方法。

//单生产者单消费者多线程代码
package
second.study; public class Test { public static void main(String[] args) { Person p = new Person(); new Thread(new Input(p)).start(); new Thread(new Output(p)).start(); } } class Person { private String name; private String sex; private boolean flag = false; public synchronized void set(String name, String sex) {//在锁对象内使用wait()和notify()方法 if (flag) {//if语句只适用于单生产者单消费者问题 try { this.wait(); } catch (Exception ex) { } } this.name = name; this.sex = sex; flag = true; this.notify();//notify()语句也只适用于单生产者单消费者问题 } public synchronized void get() { if (!flag) { try { this.wait(); } catch (Exception ex) { } } System.out.println(name + "...." + sex); flag = false; this.notify(); } } class Input implements Runnable { private Person p; public Input(Person p) { this.p = p; } @Override public void run() { int x = 0; while (true) { if (x == 0) { p.set("John", "man"); } else { p.set("丽丽", "女女女女"); } x = (x + 1) % 2; } } } class Output implements Runnable { Person p; public Output(Person p) { this.p = p; } @Override public void run() { while (true) { p.get(); } } }

多生产者多消费者问题

package second.study;

public class Test {
    public static void main(String[] args) {
        Resource resource = new Resource();
        new Thread(new Producer(resource)).start();
        new Thread(new Producer(resource)).start();
        new Thread(new Consumer(resource)).start();
        new Thread(new Consumer(resource)).start();
    }
}

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

class Producer implements Runnable{
    private Resource res;
    public Producer(Resource res) {
        this.res = res;
    }
    @Override
    public void run() {
        while(true) {
            res.set("商品");
        }
    }
}

class Consumer implements Runnable{
    private Resource res;
    public Consumer(Resource res) {
        this.res = res;
    }
    @Override
    public void run() {
        while(true) {
            res.out();
        }
    }
    
}

在JDK1.5以后,将监视器对象(锁)和监视器方法(wait();等)替换成了Lock接口对象和Condition接口对象。并且该监视器方法依然可以通过锁对象获取,并且可以创建多个锁的监视器方法对象,可以理解为可以创建多个线程池(自己的理解),用于唤醒相应线程池中的一个线程,提高速度。

package second.study;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test {
    public static void main(String[] args) {
        Resource resource = new Resource();
        new Thread(new Producer(resource)).start();
        new Thread(new Producer(resource)).start();
        new Thread(new Consumer(resource)).start();
        new Thread(new Consumer(resource)).start();
    }
}

class Resource {
    private int count;
    private String name;
    private boolean flag = false;
    Lock lock = new ReentrantLock();//Lock是一个接口,需要使用其可创建对象的子类;
    Condition condition_pro = lock.newCondition();//使用Lock对象中的方法获取监视器方法对象
    Condition condition_con = lock.newCondition();

    public void set(String name) {
        lock.lock();
        try {
            while (flag) {
                condition_pro.await();//线程0线程1进入一个线程池
            }
            this.name = name + "--" + count++;
            System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
            flag = true;
            condition_con.signal();
        } catch (InterruptedException ex) {

        } finally {
            lock.unlock();// 资源一定要释放
        }

    }

    public void out() {
        lock.lock();
        try {
            while (!flag) {
                condition_con.await();//线程2和线程2进去一个线程池
            }
            System.out.println(Thread.currentThread().getName() + "......消费者......" + this.name);
            flag = false;
            condition_pro.signal();
            
        }catch(InterruptedException ex) {
            
        }finally {
            lock.unlock();
        }
        
    }
}

class Producer implements Runnable {
    private Resource res;

    public Producer(Resource res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true) {
            res.set("商品");
        }
    }
}

class Consumer implements Runnable {
    private Resource res;

    public Consumer(Resource res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true) {
            res.out();
        }
    }

}

 如何停止线程?

  stop方法已经过时,那么停止线程只有一种,run方法结束。可以通过在主线程来控制run()方法中的标记来控制其他线程的结束。当其他线程中有wait();sleep();方法时,可能其他线程无法判断标记而使线程处于冻结状态,这时,可以使用Thread类中的interrupt()方法。当主线程执行到interrupt方法来中断线程,但是其他同步线程没有使用wait方法,这时interrupt方法对该线程不起作用,但是主线程会一直监视该线程的状态,当该线程执行到了wait方法,会立即响应中断,引发interruptException异常。然后会以下是测试代码:

package second.study;


public class Test {
    public static void main(String[] args) {
        StopThread stopThread = new StopThread();
        Thread t1 = new Thread(stopThread);
        Thread t2 = new Thread(stopThread);
        t1.start();
        t2.start();
        int num = 0;
        while(true) {
            if(num == 60) {
                t1.interrupt();
                t2.interrupt();
                System.out.println("main interrupt");//判定主线程在t1和t2线程执行wait方法之前先执行了interrupt方法。
break; } num++; System.out.println(Thread.currentThread().getName() + "......" + num); } } } class StopThread implements Runnable{ private boolean flag = true; @Override public synchronized void run() { while(flag) { try { int num = 0; while(true) { System.out.println(Thread.currentThread().getName() + "..." + num); if(num == 100) { System.out.println(Thread.currentThread().getName() + "..." + "run"); wait(); } num++; } }catch(InterruptedException ex) { System.out.println(Thread.currentThread().getName() + "..." + "Exception"); flag = false;//结束当前线程 } } } public void changeFlag() { flag = false; } }

守护线程

  也称为后台线程,当前程线程执行完毕后,后台线程会自动结束。当正在运行的线程全部为首部线程时,JVM退出。

  Thread类中的setDaemon方法。在开启线程(使用start()方法)前使用。

多线程的Join方法

  当A线程执行到了B线程的.join方法时,A就会等待,当B线程运行结束后,A线程才会执行。

  join可以用来临时加入线程。

线程优先级

  线程的优先级分为10级,可以使用setPriority(Thread.MAX_PRIORITY or Thread.MIN_PRIORITY or Thread.NORM_PRIORITY),来设置线程的优先级。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!