Java (2) multithreading

@

1、 Understanding of basic concepts

1. Program, process, thread

2. Single core CPU and multiple CPUs

3. Serial, parallel, concurrent

2、 Multithreading

1. Examples of multithreading in Java

2. Advantages of multithreading

3. When do I need multithreading

3、 Creation and use of multithreading ★★★★

1. Method 1: inherit thread class (one of the two before JDK1.5)

package com.thread;

public class ThreadTest1 {
    public static void main(String[] args) {
        new MyThread1().start();
    }
}


class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(MyThread1.currentThread().getName() + ":" + i);
        }
    }
}

//当某个线程只适用了一次的时候,也可以使用匿名类匿名对象的方式来创建多线程
package com.thread;

public class ThreadTest2 {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                System.out.println("我是子线程");
            }
        }.start();
    }
}
1)  定义子类继承Thread类。 
2)  子类中重写Thread类中的run方法。
3)  创建Thread子类对象,即创建了线程对象。 
4)  调用线程对象start方法:启动线程,调用run方法。

2. Mode 2: implement runnable interface (one of the two before JDK1.5)

3. Method 3: implement callable interface

4. Method 4: use thread pool (mainly used in development)

4、 Thread life cycle

1. Thread life cycle ★★★★

5、 Thread synchronization

1. Examples and solutions of thread safety problems

class Window implements Runnable{

    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            if (ticket > 0){
                //在这里让刚进入的线程阻塞100ms,错票的概率就会增加
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("售票,票号为: " + ticket);
                //如果在这里让刚进入的线程阻塞100ms,重票的概率就会增加
                ticket--;
            }else{
                break;
            }
        }
    }
}
public class WindowTest {
    public static void main(String[] args) {
        Window w1 = new Window();
        Thread t1 = new Thread(w1);
        Thread t2 = new Thread(w1);
        Thread t3 = new Thread(w1);

        t1.setName("窗口1");
        t1.setName("窗口2");
        t1.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

2. Synchronous code block

3. Synchronization method

4. Deadlock

package com.thread3;

public class DeadLock {
    public static void main(String[] args) {

        StringBuffer s1 = new StringBuffer();
        StringBuffer s2 = new StringBuffer();

        new Thread(){
            @Override
            public void run() {
                synchronized (s1){
                    s1.append("a");
                    s2.append("1");

                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                synchronized (s2){
                    s1.append("b");
                    s2.append("2");

                    System.out.println("s1 = " + s1);
                    System.out.println("s2 = " + s2);
                }
            }
        }.start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (s2) {

                    s1.append("c");
                    s2.append("3");

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                    synchronized (s1){
                        s1.append("d");
                        s2.append("4");

                        System.out.println("s1 = " + s1);
                        System.out.println("s2 = " + s2);
                    }


                }

        }).start();
    }
}
/*
输出结果有哪些可能
    线程1先执行,线程2后执行:ab  12  adcd  1234
    线程2先执行,线程1后执行:cd  34  cdab  3412
    都阻塞:
 */

5、lock

class A{
    private final reentrantlock lock = new reentrantlock();
    
    public void method(){
        lock.lock();//请求锁
        try{
            代码逻辑
        }finnaly{
            lock.unlock();//释放锁
        }
    }
}
class Window5 extends Thread{

    private static int ticket = 100;

    private static final reentrantlock lock = new reentrantlock();

    @Override
    public void run() {
        while (true) {
			lock.lock();
            try {
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("ticket_number=" + ticket);
                    ticket--;
                }else{
                    break;
                }
            } finally {
                lock.unlock();
            }
        }
    }
}

public class LockTest {
    public static void main(String[] args) {

        Window5 w1 = new Window5();
        Window5 w2 = new Window5();
        Window5 w3 = new Window5();

        w1.start();
        w2.start();
        w3.start();
    }
}

6、 Thread communication

//1、要先分析是不是多线程为题;
//2、在分析是否有共享数据,有---同步机制来解决

class MyPrinter implements Runnable {

    private int number = 1;

    @Override
    public synchronized void run() {
        while (true) {
            this.notify();
            if (number <= 10) {
//                this.notify();//如果我把notify放在这里,程序就不会自动结束了?  因为,放在这里,//最后一个循环的情况下,打印机二带着10进入,可以notify打印机一,再下一轮,打印机一拿着11
                //,无法进入if,无法notify打印机二,打印机二就一直阻塞在那里
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + number);
                number++;

                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }
}

public class ThreadCommunicationTest {
    public static void main(String[] args) {
        MyPrinter myPrinter = new MyPrinter();
        Thread t1 = new Thread(myPrinter);
        Thread t2 = new Thread(myPrinter);

        t1.setName("打印机一");
        t2.setName("打印机二");

        t1.start();
        t2.start();
    }
}

7、 Producer and consumer issues

/**
 * 线程通信的例子:使用两个线程打印 1-100。线程1,线程2 交替打印
 *
 * 涉及到的三个方法:
 * wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
 * notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
 * notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。
 *
 * 说明:
 * 1.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。
 * 2.wait(),notify(),notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器。
 *    否则,会出现IllegalMonitorStateException异常
 * 3.wait(),notify(),notifyAll()三个方法是定义在java.lang.Object类中。
 *
 * 面试题:sleep() 和 wait()的异同?
 * 1.相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
 * 2.不同点:1)两个方法声明的位置不同:Thread类中声明sleep(),Object类中声明wait()
 *          2)调用的要求不同:sleep()可以在任何需要的场景下调用。 wait()必须使用在同步代码块或同步方法中
 *          3)关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁。
 *
 * @author shkstart
 * @create 2019-02-15 下午 4:21
 */
class Number implements Runnable{
    private int number = 1;
    private Object obj = new Object();
    @Override
    public void run() {

        while(true){

            synchronized (obj) {

                obj.notify();

                if(number <= 100){

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ":" + number);
                    number++;

                    try {
                        //使得调用如下wait()方法的线程进入阻塞状态
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }else{
                    break;
                }
            }

        }

    }
}


public class CommunicationTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

        t1.setName("线程1");
        t2.setName("线程2");

        t1.start();
        t2.start();
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>