2月13日learn

2.11笔记:获取线程的名称:
使用Thread类中的方法getName();
String getName(); 返回该线程的名称
2.可以现货区当前正在执行的线程,使用线程的方法getNae()获取线程的名称
Static Thread currentThread()返回对当前正在执行的线程对象的引用
2.11笔记:获取线程的名称:
使用Thread类中的方法getName();
String getName(); 返回该线程的名称
2.可以现货区当前正在执行的线程,使用线程的方法getNae()获取线程的名称
Static Thread currentThread()返回对当前正在执行的线程对象的引用
线程的名称  主线程:main
新县城: thread-0thread-1   Thread-2
     */
    public void run() {

//        String name = getName();
//        System.out.println(name);
        //获取线程的方法三:
//        Thread t = Thread.currentThread();
        System.out.println(t);
        String name = t.getName();
        System.out.println(name);
        System.out.println(Thread.currentThread().getName());





设置线程的名称:(了解)
1.使用Thread中的SetName
void setName(String name)改变线程的名称,使之与参数name相同
2.创建一个带参数的构造方法,参数传递线程的名字,调用父类的带参构造方法,把线程名称传递个给父类,让父类(Thread)给子线程起个名字
package leran;

import Learn.MyThread;

public class UseThread {
    public static void main(String[] args) {
//        learn211 mt = new learn211();
//        mt.setName("扈狗子");
        //开启多线程
        MyThread("旺财").start;

    }

}


package leran;

public class learn211 extends Thread {
        public UseThread() {}
        public UseThread(String name) {
            super(name);
}
    @Override
    public void run() {
        run();

        System.out.println(Thread.currentThread().getName());
    }
}

}
public static void sleep(Long millis):使当前正在执行的线程以指定的毫秒数暂停(暂停运行)


package leran;

public class learn212 {
    public static void main(String[] args) {
        for (int i = 0; i < 61; i++) {
            System.out.println(i);
        try{
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }
    }
}


1秒打印一次


/*
   创建多线程程序的第二种方法:实现Runable接口
   Runable接口应该由那些打算通过某一线程的执行其实例的类来实现,类需要定义一个成文run的五参数方法
   Thread(Runable target)分配新的Thread对象
   Thread(Runable target,String name)分配新的Thread对象。

   实现步骤:
   创建一个Runable接口的实现类
   2.在实现类中重写Runable接口的run方法,设置线程任务
   3.创建一个Runable接口的实现类对象
   4.创建Thread类中的start方法,开启新的线程执行Run方法
package leran;

import Learn.MyThread;

public class RunableImpl implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}


package leran;

public class learn211  {
    public static void main(String[] args) {
        RunableImpl use = new RunableImpl();
        Thread t = new Thread(use);
        t.start();
        for (int i = 0; i < 20; i++) {

            System.out.println(Thread.currentThread().getName()+i);
        }

    }

}
实现Runable接口创建多雄安成程序的好处:
   1.避免了单继承的局限性
   一个类只能继承一个类,类如果继承Thread类就不能继承其他类
   实现了Runable接口,还可以继承其他的接口,实现其他的接口
   2.增强了程序的扩展性,降低了程序的耦合性(解耦
    实现Unable接口的方式,把设置线程任务和开启新线程进行了分离
    实现类中,重写了run方法:用来设置线程任务
    创建Thread类对象,调用Start方法,用来开启新的线程
    匿名内部类的方式实现线程的创建:
匿名内部类的作用和:简化代码
把子类继承父类,重写父类的方法,创建子类对象合成一步完成
把实现类接口,重写类接口的方法,创建实现类对象合成一步完成
匿名内部类的产物:子类/实现类对象,而这个类没有名字
格式:new 父类/接口(){
重写父类/接口的方法}

    public static void main(String[] args) {
        new Thread(){
            //重写run方法

            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+i);
                }
            }
        }.start();

        //多态:Runable r = new RunablkeImpl;
        Runnable r = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+"扈狗子"+i);
                }
            }
        };
        new Thread(r).start();

        /*
        也可以这么写:
        new Thread(new Runable(){
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+"扈狗子"+i);
                }
            }
        }
        }.strat();
         */
    }
}


线程安全:多线程访问了共享数据,会产生线程安全问题
package Learn213;

public class RunableImpl implements Runnable{
    private int ticket = 100;
    @Override
    public void run() {
        while (true){
            if (ticket>0){
                //提高安全出现的概率,让程序睡眠
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //这样运行就出现了代码安全问题
                System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                ticket--;

            }
        }

    }
}


package Learn213;

public class Test {
    /*
    模拟买票案例
    创建三个线程,同时开启,对共享的票进行出售

     */
    public static void main(String[] args) {
        RunableImpl run = new RunableImpl();
        Thread t0 = new Thread(run);
        Thread t1 = new Thread(run);
        Thread t2 = new Thread(run);
        t0.start();
        t1.start();
        t2.start();
    }
}

注意:线程安全问题是不能产生的,我们可以让一个线程在访问共享数据的时候,无论是否拾取了cpu的执行权,让其他线程只能当代,等待当前线程卖完票,其他线程在进行卖票
保证使用一个线程再卖票

线程同步问题:syn
1.同步代码块
synchronized(同步锁){
需要执行的代码
}
同步代码块的锁对象可以使任意一个对象
2.但是必须保证多线程使用的是一个对象
3.锁对象的作用:把同步代码块锁住,只能让一个同步代码块执行
创建一个锁对象 Object ob = new Object();

package Learn213;

public class RunableImpl implements Runnable {
    private int ticket = 100;
    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--;
                }
            }
        }
    }
}
2.同步方法:把访问了共享数据的代码抽出来,添加一个synchronized修饰符
格式:  修饰符 synchronized 返回值类型  方法名(参数列表){
}
package Learn213;

public class RunableImpl implements Runnable {
    private int ticket = 100;
    @Override
    public void run() {
        while (true) {
            useTicket();
        }
    }
    public synchronized void useTicket() {
        if (ticket > 0) {
        //提高安全出现的概率,让程序睡眠
            try {
                Thread.sleep(10);
                } catch (InterruptedException e) {
                e.printStackTrace();
            }
        //这样运行就出现了代码安全问题
        System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
        ticket--;
         }
    }
}


静态方法
package Learn213;

public class RunableImpl implements Runnable {
    private  static int ticket = 100;
    @Override
    public void run() {
        while (true) {
            useTicket();
        }
    }
    public static synchronized void useTicket() {
        if (ticket > 0) {
        //提高安全出现的概率,让程序睡眠
            try {
                Thread.sleep(10);
                } catch (InterruptedException e) {
                e.printStackTrace();
            }
        //这样运行就出现了代码安全问题
        System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
        ticket--;
         }
    }
}

3.锁机制
void lock()获取锁
void unlock()释放锁
使用步骤:
1.在成员位置创建一个ReentrantLovk对象
2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
3.在可能会出现安全问题的代码后调用Lock接口中的方法lock释放锁



package Learn213;

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

public class RunableImpl 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);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                //这样运行就出现了代码安全问题
//                System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
//                ticket--;
//            }
//            l.unlock();
            if (ticket > 0) {
                //提高安全出现的概率,让程序睡眠
                try {
                    Thread.sleep(10);
                    System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
                    ticket--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {//wulun
                    l.unlock();//   无论程序是否异常,都把所给解开
                }
                //这样运行就出现了代码安全问题

            }


        }
    }
}
线程状态:

等待唤醒:
package BaS;

public class Ssb {
    /*
    等待换洗干礼:线程之间的通信
    创建一个顾客线程(消费者):告知老板的种类和数量 调用wait方法,放弃cpu执行,进入WATTING状态(无线等待)
    创建一个老板线程:花费五秒做包子,做好包子之后,调用notify方法,唤醒顾客吃包子
    注意:顾客和老板线程必须使用同步代码块包裹起来保证等待好唤醒只能有一个在执行
    同步使用的锁对象必须保证唯一
    只能锁对象才能调用wait和notify方法

     */
    public static void main(String[] args) {

        Object obj = new Object();
        new Thread(){
            @Override
            public void run() {
                //保证等待和唤醒的线程只能有一个执行,需要使用同步技术
                synchronized (obj){
                    System.out.println("告知老板的种类和数量");
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("包子已经做好了,开吃");
                }

            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj){
                    System.out.println("老板五秒钟之后做好包子,告知顾客可以吃包子了");
                    obj.notify();

                }
            }
        }.start();
    }
}





等待唤醒:
package BaS;

public class Ssb {
    /*
    等待唤醒:线程之间的通信
    创建一个顾客线程(消费者):告知老板的种类和数量 调用wait方法,放弃cpu执行,进入WATTING状态(无线等待)
    创建一个老板线程:花费五秒做包子,做好包子之后,调用notify方法,唤醒顾客吃包子
    注意:顾客和老板线程必须使用同步代码块包裹起来保证等待好唤醒只能有一个在执行
    同步使用的锁对象必须保证唯一
    只能锁对象才能调用wait和notify方法

     */
    public static void main(String[] args) {

        Object obj = new Object();
        new Thread(){
            @Override
            public void run() {
                //保证等待和唤醒的线程只能有一个执行,需要使用同步技术
                synchronized (obj){
                    System.out.println("告知老板的种类和数量");
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("包子已经做好了,开吃");
                }

            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj){
                    System.out.println("老板五秒钟之后做好包子,告知顾客可以吃包子了");
                    obj.notify();

                }
            }
        }.start();
    }
}

 /*进入到timewaiting(等待计时)有两种方式
        1.使用sleep(long m)的方法,在毫秒值之后,线程睡醒进入到Runnable/Blocked状态
        2.使用wait(Long m)方法,wait方法如果在毫秒值之后还没有被notify唤醒,就会自动唤醒,线程睡醒进入到Runnable/Blocked状态
               唤醒的方法:除了notify
               还有notifyAll()唤醒所有的锁

         */

如果有两个顾客 notify变成notifyAll这样两个顾客就可以一起吃包子
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值