java学习日记 多线程

1、继承Thread类

一个类只要继承了Thread类,就是多线程实现类。

必须覆写 run()方法,  public void run()
在线程启动时,调用start()方法,  public void start()。
class MyThread extends Thread{
    private String name;
    public MyThread(String name){  //定义构造方法
        this.name = name;
    }
    @Override
    public void run() {
        for (int i = 0;i<200;i++){
            System.out.println(this.name+"-->"+i);
        }
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread("A");
        MyThread myThread1 = new MyThread("B");
        MyThread myThread2 = new MyThread("C");

        myThread.start();
        myThread1.start();
        myThread2.start();
    }
}

运行结果:

C-->0
B-->0
A-->0
A-->1
A-->2
B-->1
B-->2
B-->3
B-->4......
C-->195
C-->196
C-->197
C-->198
C-->199

2、实现Runnable接口

class MyThread implements Runnable{
    private String name;
    public MyThread(String name){  //定义构造方法
        this.name = name;
    }
    @Override
    public void run() {
        for (int i = 0;i<200;i++){
            System.out.println(this.name+"-->"+i);
        }
    }
}

public class ThreadDemo1 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread("A");
        MyThread myThread1 = new MyThread("B");
        MyThread myThread2 = new MyThread("C");

        new Thread(myThread).start();
        new Thread(myThread1).start();
        new Thread(myThread2).start();

    }
}

运行结果:

B-->0
B-->1
C-->0
A-->0
A-->1
C-->1
......
B-->196
B-->197
B-->198
B-->199

3、Thread类不能实现资源共享

class MyThread1 extends Thread{
    private int ticket =5;

    @Override
    public void run() {
        for (int x =0;x<100;x++){
            if (ticket>0){
                System.out.println("卖票,ticket="+this.ticket--);
            }
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        MyThread1 myT = new MyThread1();
        MyThread1 myT2 = new MyThread1();
        myT.start();
        myT2.start();
    }
}

运行结果:(两个线程各自卖票)

卖票,ticket=5
卖票,ticket=5
卖票,ticket=4
卖票,ticket=3
卖票,ticket=4
卖票,ticket=3
卖票,ticket=2
卖票,ticket=2
卖票,ticket=1
卖票,ticket=1

4、实现Runnable接口可以实现资源共享

class MyThread1 implements Runnable{
    private int ticket =5;

    @Override
    public void run() {
        for (int x =0;x<100;x++){
            if (ticket>0){
                System.out.println("卖票,ticket="+this.ticket--);
            }
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        MyThread1 myT = new MyThread1();
        new Thread(myT).start();
        new Thread(myT).start();
        new Thread(myT).start();
    }
}

运行结果:

卖票,ticket=5
卖票,ticket=2
卖票,ticket=1
卖票,ticket=3
卖票,ticket=4

5、取得和设置线程名称

class MyThread2 implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
public class ThreadNameDemo1 {
    public static void main(String[] args) {
        MyThread2 my = new MyThread2();
        new Thread(my,"A").start();
        new Thread(my).start();  //自动命名
        new Thread(my,"B").start();
        new Thread(my).start();
        new Thread(my).start();

    }
}

运行结果:

Thread-0
Thread-2
Thread-1
B
A

6、主方法也是线程

class MyThread2 implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
public class ThreadNameDemo1 {
    public static void main(String[] args) {
        MyThread2 my = new MyThread2();
        new Thread(my,"A").start();
        new Thread(my).start();  //自动命名
        new Thread(my,"B").start();
        my.run();

    }
}

运行结果:

main
B
A
Thread-0

7、线程的休眠

class MyThread2 implements Runnable{
    @Override
    public void run() {
        for (int x = 0; x<5;x++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+",x="+x);
        }
    }
}
public class ThreadNameDemo1 {
    public static void main(String[] args) {
        MyThread2 my = new MyThread2();
        new Thread(my,"A").start();
        new Thread(my,"B").start();
        new Thread(my,"C").start();
        new Thread(my,"D").start();
    }
}

运行结果:

A,x=0
D,x=0
C,x=0
B,x=0
A,x=1
C,x=1
D,x=1
B,x=1
C,x=2
D,x=2
A,x=2
B,x=2
D,x=3
A,x=3
C,x=3
B,x=3
C,x=4
D,x=4
A,x=4
B,x=4

8、线程优先级

class MyThread2 implements Runnable{
    @Override
    public void run() {
        for (int x = 0; x<10;x++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        }
    }
}
public class ThreadNameDemo1 {
    public static void main(String[] args) {
        MyThread2 my = new MyThread2();
        Thread thread = new Thread(my,"A");
        Thread thread1 = new Thread(my,"B");
        Thread thread2 = new Thread(my,"C");
        thread.setPriority(Thread.MAX_PRIORITY); //10
        thread1.setPriority(Thread.MIN_PRIORITY); //1
        thread2.setPriority(Thread.NORM_PRIORITY); // 5
        thread.start();
        thread1.start();
        thread2.start();
    }
}

9、问题的引出

class MyThread1 implements Runnable{
    private int ticket =5;

    @Override
    public void run() {
        for (int x =0;x<20;x++){
            if (ticket>0){
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"卖票,ticket="+this.ticket--);
            }
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        MyThread1 my = new MyThread1();
        new Thread(my,"A").start();
        new Thread(my,"B").start();
        new Thread(my,"C").start();
    }
}

运行结果:

A卖票,ticket=4
C卖票,ticket=5
B卖票,ticket=3
C卖票,ticket=2
B卖票,ticket=1
A卖票,ticket=0
C卖票,ticket=-1

10、使用同步解决问题

同步代码块:

class MyThread1 implements Runnable{
    private int ticket =59;

    @Override
    public void run() {
        for (int x =0;x<200;x++){
            synchronized (this){  //当前对象只允许一个对象进入
                if (ticket>0){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"卖票,ticket="+this.ticket--);
                }
            }
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        MyThread1 my = new MyThread1();
        new Thread(my,"A").start();
        new Thread(my,"B").start();
        new Thread(my,"C").start();
        new Thread(my,"D").start();
    }
}

同步方法:

class MyThread1 implements Runnable{
    private int ticket =59;

    @Override
    public void run() {
        for (int x =0;x<200;x++){
            this.sale();  // 调用同步方法
        }
    }
    public synchronized void sale(){  //同步方法
        if (ticket>0){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"卖票,ticket="+this.ticket--);
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        MyThread1 my = new MyThread1();
        new Thread(my,"A").start();
        new Thread(my,"B").start();
        new Thread(my,"C").start();
        new Thread(my,"D").start();
    }
}

11、生产者-消费者

class Info{
    private String name;
    private String content;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

class Pro implements Runnable{
    private Info info;
    public Pro(Info info){
        this.info = info;
    }

    @Override
    public void run() {
        for (int x = 0; x<50;x++){
            if (x%2==0){
                this.info.setName("cathy");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.setContent("student");
            }else {
                this.info.setName("w");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.setContent("wo");
            }
        }
    }
}

class Cus implements Runnable{
    private Info info;
    public Cus(Info info){
        this.info = info;
    }

    @Override
    public void run() {
        for (int x = 0;x<50;x++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(this.info.getName()+"-->"+this.info.getContent());
        }
    }
}
public class ProCus_ThreadDemo1 {
    public static void main(String[] args) {
        Info info = new Info();
        new Thread(new Pro(info)).start();
        new Thread(new Cus(info)).start();
    }
}

运行结果:

w-->student
w-->wo
w-->student
w-->student
w-->student
w-->student
cathy-->wo
cathy-->wo
.........

产生问题:1)错位  2)重复生产,重复取出

解决错位问题——加入同步

class Info{
    private String name;
    private String content;

    public synchronized void set(String name,String content){
        this.setName(name);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.setContent(content);
    }

    public synchronized void get(){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.getName()+"-->"+this.getContent());
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

class Pro implements Runnable{
    private Info info;
    public Pro(Info info){
        this.info = info;
    }

    @Override
    public void run() {
        for (int x = 0; x<50;x++){
            if (x%2==0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.set("cathy","student");
            }else {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.set("w","wo");
            }
        }
    }
}

class Cus implements Runnable{
    private Info info;
    public Cus(Info info){
        this.info = info;
    }

    @Override
    public void run() {
        for (int x = 0;x<50;x++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.info.get();
        }
    }
}
public class ProCus_ThreadDemo1 {
    public static void main(String[] args) {
        Info info = new Info();
        new Thread(new Pro(info)).start();
        new Thread(new Cus(info)).start();
    }
}
解决重复问题——加入等待与唤醒

java学习日记  多线程

class Info{
    private String name;
    private String content;
    private boolean flag =true; //flag=true表示可以生产,但是不能取走。flag=false表示不可以生产,可以取走

    public synchronized void set(String name,String content){
        if (!flag){
            try {
                super.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.setName(name);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.setContent(content);
        flag = false;
        super.notify();
    }

    public synchronized void get(){
        if (flag){
            try {
                super.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.getName()+"-->"+this.getContent());
        flag = true;
        super.notify();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

class Pro implements Runnable{
    private Info info;
    public Pro(Info info){
        this.info = info;
    }

    @Override
    public void run() {
        for (int x = 0; x<100;x++){
            if (x%2==0){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.set("cathy","student");
            }else {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.set("w","wo");
            }
        }
    }
}

class Cus implements Runnable{
    private Info info;
    public Cus(Info info){
        this.info = info;
    }

    @Override
    public void run() {
        for (int x = 0;x<100;x++){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.info.get();
        }
    }
}
public class ProCus_ThreadDemo1 {
    public static void main(String[] args) {
        Info info = new Info();
        new Thread(new Pro(info)).start();
        new Thread(new Cus(info)).start();
    }
}