欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java之多线程

程序员文章站 2023-12-23 14:03:40
...

继承Thread,并重写run方法,start()开始,进程为抢占式

MyThread mt = new MyThread();  //添加一个新线程进入cpu抢占资源
        mt.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("main: "+i);
        }

创建一个进程的第二种方法,实现Runnable接口,重写run方法

public static void main(String[] args) {
        MyThreadRunnable mt = new MyThreadRunnable();//实现了Runnable接口
        Thread t = new Thread(mt);
//        mt.start();  mt没有start方法要转换成Thread
        t.start();
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+": "+i);
        }
    }

好处:避免了单继承的局限性,增强了程序的扩展性,降低了程序的耦合性,多用这种方式

 

线程安全问题:用线程同步技术解决

同步代码块:

 Object obj = new Object();

    @Override
    public void run() {
        while (true){
            synchronized (obj){  //同步代码块,解决线程安全问题
                if(ticket>0){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                    ticket--;
                }
            }
        }
    }

解决线程安全问题的二种方案:使用同步方法使用步骤:
    1.把访问了共享数据的代码抽取出来,放到一个方法中

    2.在方法上添加 Synchronized修饰符

   格式:定义方法的格式

            修饰符 synchronized  返回值类型   方法名(参数列表){

                   可能会出现线程安全问题的代码(访问了共享数据的代码)

           }

public synchronized void payTickt(){
        if(ticket>0){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
            ticket--;
        }
    }

第三种方式lock锁

public class LockThread  implements Runnable{
    private  int ticket = 100;
    Lock l = new ReentrantLock();
    @Override
    public void run() {
        while (true){
            l.lock();
            if(ticket>0){
                try {
                    Thread.sleep(10);
                    System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                    ticket--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    l.unlock();
                }
            }
        }
    }
}

等待和唤醒Object obj.wait()和Object obj.notify           只有锁对象obj才可以使用wait和notify

 

线程池:jdk1.5以后有提供现成的线程池

java.utt. concurrent, Executors:线程池的工厂类,用来生成线程池

/*
            线程池的使用步骤
                1.使用线程池的工厂类 Executors里边提供的静态方法 newFixedThreadpooL生产一个指定线程数量的线程池
                2.创建一个类,实现 Runnable接口,重写run方法,设置线程任务
                3.调用 Executorservice中的方法 submit,传递线程任务(实现类),开启线程,执行run方法
                4.调用 Executonservice中的方法 shutdown销毁线程池(不建议执行)
 */
public class DemoThreadPool {
    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(2);
        es.submit(new RunnableImpl());
        es.submit(new RunnableImpl());
        es.submit(new RunnableImpl());

        es.shutdown();
    }
}

 

相关标签: 学习

上一篇:

下一篇: