Java-线程和进程创建with多线程安全多线程同步线程锁机制(ThreadsANDProcesses_create_security_synchronous_lock.class)



//手机终端 请上下左右 滑动屏幕 翻看更全!
//package Main;
import java.lang.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//
/**
 * @time(时间):-2019/05/31
 * @role(谁):-杨木发
 * @modify(修改)-:
 * -@time:
 * -@role:
 *
 * @SaySomething(我觉得我应该说点什么的):
    :-While doing summary(边做边总结):
 *      :继承Thread类方式和实现Runnable接口方式其各自的有点,既然存在即是有合理的地方的,
 *       继承:1、java中,类的单继承的,如果继承了Thread类则该类就不能再有其他父类; ,
 *             2、从操作上分析,继承方式更加简单,自定义与获取线程名称也比前者简单。
 *       实现接口:1、java中类可以多实现或继承并实现还可以实现其他接口。
 *                 2、从操作上说实现接口反射要比继承的方式复杂好多,获取与自定义线程名称也是如此,
 *                      他需要使用Thread.crrentThread(); 方法来获取。
 *                 3、从资源共享上分析,实现接口方式可以共享资源。(Thread方式加static也可以实现但是,一般情况下别这样设计)
 *      :
 *      -开启一个进程方式一:(Runtime runt = new Runtime.getRuntime();
 *                      runt.exec("notpad");  同cmd 输入 notpad 打开记事本 )
 *      -开启一个进程方式二:ProcessBuilder pd = new ProcessBuilder("notpad");
 *                          pd.start();       同cmd 输入 notpad 打开记事本 )
 *      -创建线程传统的两种方式:1:继承Thread类、2:实现Runnable接口,然后分别覆写和实现run()方法。
 *      -
 * @Attention(注意!):
 *      1、main也是一个线程(主线程)
 *      2、启动线程时是不能直接调用run()方法,因为这样和调用普通方法没有区别并不会开启新的线程,
 *          应该调用start()方法,start()他底层会去调用run()这样才能正常开启。
 *      3、一个线程只启动一次。
 *      4、线程类只有一个(Thread),Runnable接口与他的实现类并不是,如果采用Runnable方式创建线程
 *         则需要把Runnable实现类对象传入Thread。
 *      5、普通线程一旦启动将和主线程同一级别,即便主线程运行已结束,普通线程如果没有运行完它将依    然继续运行。
 *      6、Thread方式自定义线程名称:需要提供一个构造器传入参数后调用父类构造器并传入参数,super.getName() 获取系统线程默认名称
 *      7、Runnable接口方式自定义线程名称:在new Thread对象传入Runnable对象时的同一参数列表传入String昵称例如:
 *         new Thread(Eat,"一号线程-").start(); (其中eat为实现Runnable接口的类的对象),如何通过调用 static Thread currentThread();方法
 *         (此方法返回对当前正在执行的线程对象的引用)例如:String name = Thread.curreentRhtead().getName();  又例如;
 *          System.out.println(Thread.currentThread().getName()+"吃了第"+ appleNumber-- +"个苹果█");
 *      8、如果需要实现多个线程公用一个对象资源的情况这使用Runnable接口实现类对象传入Thread类为合适。
 *      9、在线程方法上不能使用throws来声明抛出异常只能使用try-cathy来处理异常,因为子类覆盖父类的方法原则,
 *          子类不能抛出新的异常;在Runnable接口中的run();方法都没有声明异常。(public abstract void run();)
 *      10、在使用synchronized进行各种形式的同步操作时对于非static方法同步锁就是this,
 *          对于static方法即使用当前方法所在类的字节码对象;且不易使用synchronized修饰run()方法否则会导致
 *          某个线程一旦就去就会把所有的代码执行完了才出来,其他线程就Over了(应该吧需要同步的方法自定义在一个用synchronized修饰的方法中,然后在run中调用)。
 *      11、synchronized作用域越大性能损耗越大所以应尽量减小作用域
 *      12、
 */

public class ThreadsANDProcesses_create_security_synchronous_lock {
    public static void main(String[] args) throws Exception {

//        createThreadsANDProcessesDemo cTAPD = new createThreadsANDProcessesDemo();
//        cTAPD.RUN();
//    }
//}

/**
//class createThreadsANDProcessesDemo {
//    public void RUN() {


        //System.out.println("木发打游戏"+i);
        //创建开启一个进程,方式一
        //Runtime runtime = Runtime.getRuntime();
        //runtime.exec("notepad");
        //创建开启一个进程,方式二
        //ProcessBuilder pd = new ProcessBuilder("notepad");
        //pd.start();
  */

/**
        //创建开启一个线程,方式一
        //musicThread thread = new musicThread("发哥哥Music线程 0 ");
        //创建开启一个线程,方式二
        //gameThread GT = new gameThread("打游戏线程-");
        //Thread TR = new Thread(GT);
        //Test For
 */


/**       for (int i = 0; i < 400; i++) {
            System.out.println("吃脆脆骨。。。" + i);//主线程
            if (i == 0) {//满足条件时表示开启一个线程且这个线程将执行run里的代码,
                // 如果不不加if折表示开启i个线程就造成执行i次run
                thread.start();//开启听音乐线程
            }
            if (i == 0) {
                TR.start();//开启打游戏线程
            }


            //匿名内部类创建开启线程(Thread类方式)
            if (i == 0) {
                new Thread() {
                    @Override
                    public void run() {
                        for (int j = 0; j < 400; j++) {
                            System.out.println("匿名内部类-躺着看电影" + j);
                        }
                    }
                }.start();
            }
            //匿名内部类创建开启线程(Runnable接口方式)
            if (i == 0) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int j = 0; j < 400; j++) {
                            System.out.println("匿名内部类-打豆豆" + j);
                        }
                    }
                }).start();
            }

            if(i==0){
                new musicThread("音乐线程 1 ").start();
                new musicThread("音乐线程 2 ").start();
            }

        }



*/
        //此种方法会造成多个线程同时重复吃一个苹果的情况!
        //new person3("一号线程-").start();
        //new person3("二号线程-").start();
        //new person3("三号线程-").start();


        //new三个对象就代表有三个分别有50个苹果的对象,so...
        // 要想解决此问题得使用Runnable方式把同一个继承Thread方式的对象传入实现Runnable对象.
        //eat Eat = new eat();
       //new Thread(Eat,"一号线程-").start();
        //new Thread(Eat,"二号线程-").start();
        //new Thread(Eat,"三号线程-").start();


        //线程安全
        //当线程并发访问同同意资源时,可能出现线程不安全问题,(同一资源出现多个线程不可控的多操作)
        //上面三个使用Runnable接口实现方式的时候回发现线程做生意没发现什么异常是因为问题不该明显,
        //为了让问题更加明显,使用Thread.sleep(1000); 方法让线程沉睡1000毫秒一段时间让其他线程去抢占资源即可。
        //sleepDemo sd = new sleepDemo();
        //new Thread(sd,"帅帅的线程-").start();
        //new Thread(sd,"帅帅的线程二").start();
        //要解决此问题(即用 当a线程加入操作时b等线程只能等待a操作完成后出来依次进入)则可以有如下三种方式:
        //
        // 方式一:同步代码块(synchronized());在任何时候最多允许一个线程拥有同步锁,
        //                                      谁拿到锁进入代码块,其他线程只能在外面等着。
        //synchronizedCodeBlock sd = new synchronizedCodeBlock();
        //new Thread(sd,"帅帅的线程-").start();
        //new Thread(sd,"帅帅的线程二").start();
        //new Thread(sd,"帅帅的线程三").start();
        //
        // /方式二:同步方法(synchronized());;用synchronize修饰的方法即为同步方法,保证某线程执行该方法的时候,其他线程只能在外等着。
        //synchronizedMethod SMF = new synchronizedMethod();
        //new Thread(SMF,"张三").start();
        //new Thread(SMF,"李四").start();
        //new Thread(SMF,"王五").start();
        //
        //方式三:锁机制(lock);lock机制提供了比synchronized代码块和synchronized()方法更加方便的锁定操作,
        //                       同步代码块/同步方法具有的功能lock都有,除此之外更强大,更体现面向想对象。
        LockingMechanism LM = new LockingMechanism();
        new Thread(LM,"锁线程一").start();
        new Thread(LM,"锁线程二").start();
        new Thread(LM,"锁线程三").start();

    }
}

    //听音乐线程类 (继承Thread的方式)
    class musicThread extends java.lang.Thread{
    //往父类传入来自子类构造的线程命名参数
    public musicThread(String name){
        super(name);
    }
        @Override
        public void run() {
            for (int i = 0; i <400 ; i++) {
                System.out.println(super.getName()+"优雅的听音乐。。。"+i);// super.getName() 获取系统线程默认名称
            }
        }
    }

    //打游戏线程类(实现Runnable接口并把Runnable实现类对象传入Thread的方式)
    class  gameThread extends Thread implements Runnable {

        public gameThread(String name){
            super(name);
        }
        @Override
        public void run() {
            for (int i = 0; i <400 ; i++) {
                System.out.println("打游戏!矫捷的手指游走在键盘之间,帅!"+i);
            }
        }
    }

    //继承Thread类吃苹果线程
class person3 extends java.lang.Thread{
   private int appleNumber = 50 ;
        public person3(String name){
            super(name);
        }
        @Override
        public void run() {
            for (int i = 0; i < 50 ; i++) {
                if (i>=0||i<50){
                    System.out.println(super.getName()+"吃了第"+ appleNumber-- +"个苹果");
                }
            }
        }
    }
//实现Runnable接口方式吃苹果类
class eat implements Runnable{
    private int appleNumber =50;
    @Override
    public void run() {
        for (int i = 0; i < 50 ; i++) {
            if (appleNumber>=0){
                System.out.println(Thread.currentThread().getName()+
                        "吃了第"+appleNumber--+"一个苹果♥█♡◁▷▓۞卐卍");
            }
        }
    }
}

class sleepDemo implements Runnable{
    private int sum = 200 ;
    @Override
    public void run() {
        System.out.println("begin...");
        for (int i = 0; i < 200; i++) {
            if(sum>0){
                System.out.println(Thread.currentThread().getName()+"吃了第"+sum+"个苹果♥");
                try {
                    Thread.sleep(10);//调用Thread()方法沉睡线程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sum--;
            }

        }
        System.out.println("ending...");
    }
}


class synchronizedCodeBlock implements Runnable{
    private int sum = 200 ;
    @Override
    public void run() {
        System.out.println("begin...");

           for (int i = 0; i < 200; i++) {
               //同步代码块
               synchronized(this) {//this表示本类对象(synchronizedCodeBlock),该对象为多线程共享资源
                   if (sum > 0) {
                   try {
                       Thread.sleep(100);//调用Thread()方法沉睡线程
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   System.out.println(Thread.currentThread().getName() + "吃了第" + sum + "个苹果♥");
                   sum--;
               }
           }
       }
        System.out.println("ending...");
    }
}


class synchronizedMethod implements Runnable {
    private int sum = 200 ;
    @Override
    public void run() {
        System.out.println("begin...");
        for (int i = 0; i < 200; i++) {
            eat();
        }
        System.out.println("ending...");
    }
    synchronized private void eat(){//同步方法
        if (sum > 0) {
            try {
                Thread.sleep(100);//调用Thread()方法沉睡线程
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "吃了第" + sum + "个苹果♥");
            sum--;
        }
    }
}

//饿汉式双重锁机制
class Lazy {
    private void Lazy(){}
    public static Lazy lazy = null ;
    public static Lazy getLazy(){
        if(lazy==null){
            synchronized(Lazy.class){
                if(lazy==null){
                    lazy = new Lazy();
                }
            }
        }
        return lazy;
    }
    public void sort(){
        //
    }
}


//锁机制
class LockingMechanism implements Runnable{
    private int number =150;
    private final Lock lock = new ReentrantLock();//创建锁对象
    public void run(){
        for (int i = 0; i <150 ; i++) {
            eat();
        }
    }
    private void eat(){
        //进入方法 立即枷锁。
        lock.lock();//获取锁(加锁)
        if(number>0){
            try {
                Thread.sleep(10);//睡眠线程,睡他是为了让问题暴露的更明显,以方便解决
                System.out.println(Thread.currentThread().getName() + "吃了第" + number + "个苹果♥");
                number--;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();//释放锁
            }
        }
    }
}

/*-------------------反爬声明o()咻咻咻--------------------
 

作者:**杨木发** 版权声明: 本文为博主倾情原创文章,整篇转载请附上源文链接!

如果觉得本文对你有所收获,你的请评论点赞 与

合理优质的转发也将是鼓励支持我继续创作的动力,

更多精彩可百度搜索 杨木发 或:

个人网站:杨木发的自留地 - 此地无银三百两

GitHub:https://github.com/yangmufa

坚持创作 善于总结 开源共享 高质进步。

-------------------反爬声明o()咻咻咻--------------------*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员菜鲲(原)

你的鼓励将是我创作的最大动力o

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值