java多线程的学习

进程与线程的关系

一个程序至少有一个进程,一个进程至少有一个线程,一个线程只属于一个进程.
火车站可以看作一个进程
火车站中的售票窗口可以看作一个线程

实现线程的多种方式

实现线程的第一种方式

通过继承Thread实现

public class Main {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start(); //开启一个新的分支,自动调用run方法
        for (int i = 0; i < 1000; i++) {
            System.out.println("主线程---->" + i);
        }
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(this.getName() + "线程---->" + i);
        }
    }
}

实现线程的第二种方式

通过实现Runnable接口实现

public class Main {
    public static void main(String[] args) {
        MyRunning myRunning = new MyRunning();  //创建一个可运行的对象
        Thread thread = new Thread(myRunning); //封装为线程对象
        thread.start();
        for (int i = 0; i < 300; i++) {
            System.out.println("主线程--->" + i);
        }
    }
}

class MyRunning implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 300; i++) {
            System.out.println("分支线程--->" + i);
        }
    }
}

实现线程的第三种方式

实现Callable接口    //可以获取线程的返回值

public class Main {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable myCallable = new MyCallable();
        FutureTask task = new FutureTask(myCallable);  //未来任务类
        Thread t = new Thread(task);
        t.start();
        for (int i = 0; i < 300; i++) {
            System.out.println("主线程-->" + i);
        }
        Object obj = task.get();    //获取返回值
        System.out.println(obj);
    }
}

class MyCallable implements Callable {
    @Override
    public Object call() throws Exception {
        for (int i = 0; i < 300; i++) {
            System.out.println("f线程-->" + i);
        }
        return 10;
    }
}

线程的一些方法

getName

this.getName();//获取线程名字

注:该方法需要在线程内才可使用,继承Runnable接口不能使用,原因是因为它并不是一个线程只是一个对象,需要获取当前线程才能使用,如下

    @Override
    public void run() {
        Thread nowThread = Thread.currentThread();   //获取当前线程
        for (int i = 0; i < 300; i++) {
            System.out.println(nowThread.getName() + "线程--->" + i);
            // System.out.println(this.getName()+"线程--->" + i);
            // System.out.println(super.getName()+"线程--->" + i);
        }
    }

sleep

Thread.sleep(1000*5)  //休眠5s

interrupt

thread.interrupt();     //其作用是中断此线程(此线程不一定是当前线程,而是指调用该方法的Thread实例所代表的线程),但实际上只是给线程设置一个中断标志,线程仍会继续运行。
 

public class Main {
    public static void main(String[] args) throws InterruptedException {
        MyRunning myRunning = new MyRunning();
        Thread thread = new Thread(myRunning);
        thread.start();
        System.out.println("---主线程---");
        Thread.sleep(1000 * 5);
        thread.interrupt();  //通过异常终止休眠
    }
}

class MyRunning implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(1000 * 60);
        } catch (InterruptedException e) {
            e.printStackTrace(); //打印信息,如果为throw异常,则不向下运行
        }
        System.out.println("hello word");
    }
}

setPriority

设置线程优先级
默认为5,10最高,1最低
Thread thread = new Thread();
thread .setPriority(10);

yield

Thread.yield();
线程让位

join

//线程合并
Thread thread = new Thread();
thread.join();
thread线程先执行,被合并的线程后执行

关于线程安全

线程不安全的条件

1.多线程并发
2.有共享数据
3.共享数据有修改的行为

解决线程安全

线程同步机制
synchronized (this){  //this指当前对象,想同步哪一个对象填哪一个对象
//线程同步代码块
}
注:建议使用在实例方法上。效率高

生产者和消费者模式

其中的用到的方法

wait()方法的作用
Object o=new Object();
o.wait();
让正在o对象上活动的线程进入等待状态,无限期等待,直到被唤醒。
notify()方法的作用
o.notify();
将正在o对象上等待的线程唤醒

public class Main {

    public static void main(String[] args) {
        List list = new ArrayList();
        Thread thread1 = new Thread(new Produce(list));   //生产者线程
        Thread thread2 = new Thread(new Consume(list));   //消费者线程

        thread1.setName("生产者");
        thread2.setName("消费者");
        thread1.start();
        thread2.start();
    }
}

class Produce implements Runnable {  //生产者类
    private List list;

    public Produce(List list) {
        this.list = list;
    }

    @Override
    public void run() {

        while (true) {
            synchronized (list) {
                if (list.size() > 0) {
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                Object o = new Object();
                list.add(o);
                System.out.println(Thread.currentThread().getName() + "生产了一个产品");
                list.notify();
            }
        }
    }
}

class Consume implements Runnable {   //消费者类

    private List list;

    public Consume(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (list) {
                if (list.size() == 0) {
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                list.remove(0);
                System.out.println(Thread.currentThread().getName() + "消费了一个产品");
                list.notify();
            }
        }
    }
}

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值