java多线程知识回顾

线程创建的方式 有两种

第一种是继承Thread类 重写run方法 (个人偏向这一种实际中这种用的较多)

例如

public class MyThead extends  Thread {

    int j=20;
    public void run(){
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(this.getName()+",i="+j--);
        }
    }
}

 这种自己测试时也很多人写

new Thread(new Runnable() {
@Override
public void run() {

}
}).start(); 这样不好控制线程但是平时写一下也没关系

第二种第二种是实现Runnable接口
public class Thread3 implements  Runnable{
    @Override
    public void run() {

        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("接口Runnable"+",i="+i--);
        }

    }

}

  主线程调用方式

 public static void main(String[] args) throws InterruptedException {


        MyThead myThead= new MyThead();
        MyThread1 myThead1= new MyThread1();
        Thread3 thread3=new Thread3();
        //thread3.run();//这样不是开线程运行
        Thread t = new Thread(thread3);
        t.start();
        myThead.start();
        myThead1.start();


    }

  个人还是倾向继承Thead 赶脚方便

-------------------------------------------------------------------------------------------------------------------

线程实现后最多的也就是用到线程同步了(synchronized 关键字 其他锁以后说)

来自

https://www.cnblogs.com/blueSkyline/p/8598099.html
自己大一学的时候感觉懵逼的不行 ...三年后清晰不少
public class SynMethod {
    private static final Object staticLockObj = new Object();
    /**
     * 对象锁,代码级别,同一对象争用该锁,this为SynMethod实例,synchronized的锁绑定在this对象上
     */
    public void method1() {
        synchronized (this) {
            for (int i = 0; i < 100; i++) {

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

    /**
     * 对象锁,方法级别,同一对象争用该锁,普通(非静态)方法,synchronized的锁绑定在调用该方法的对象上,与上一个写法含义一致()
     */
    public synchronized void method2() {
        for (int i = 0; i < 500; i++) {
            System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
        }
    }

    /**
     * 对象锁,代码级别,同一类争用该锁,绑定在staticLockObj上,不同SynMethod实例,拥有同一个staticLockObj对象
     */
    public void method3() {
        synchronized (staticLockObj) {
            for (int i = 0; i < 50; i++) {
                System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
            }
        }
    }

    /**
     * 类锁,代码级别,同一类争用该锁
     */
    public void method4() {
        synchronized (SynMethod.class) {
            for (int i = 0; i < 50; i++) {
                System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
            }
        }
    }

    /**
     * 类锁,方法级别,同一类争用该锁,synchronized的锁绑定在SynMethod.class上
     */
    public static synchronized void staticMethod() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
        }
    }
}

  解释的比较清楚 自己试一试才是关键 ........  

为什么能加上去锁呢?对象头部都有一些标志位...详情百度

 ------------------------------------------------------------------------------------------

大一的时候看过一个多线程简单的例子 火车站卖票的例子 一个线程相当于一个窗口 开多个窗口同时买票 且不重复

但是看完之后有点懵逼 模棱两可也就过去了 现在明白不少 主要是上面的synchronized关键字 当然也可以用其他锁实现 先贴一下自己的例子

public class Station extends Thread {
    public Station(String name) {
        super(name);// 给线程名字赋值
    }
   static int  tick=50;

    @Override
    public void run() {
        while (tick>0)
        {
            synchronized (Station.class)  //同步这里不能写this 可以是类 this 只会在本对象生效 new 一个新的没办法共同使用
            {
                if (tick>0)
                {
                    System.out.println(getName()+"卖了第"+tick+"张票");
                    tick--;
                }else
                {
                    System.out.println("票已经卖完");
                }

            }

            try {
                sleep(100);//这里让线程不得到CUP 一下否则可能一个线程把事情干完了 达不到模拟效果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

  synchronized (Station.class) 可以使用注意不要用this 那样窗口买票可能会重复的...也可以 在station 类里面new 一个没用的object对象 用哪个对象当钥匙(因为你new 再多的对象还是用那一个object 看看synchronized 的前面的例子运行一下就明白很多) 这两种解决都可以 

买票main函数

 Station station1=new Station("窗口1");
        Station station2=new Station("窗口2");
        Station station3=new Station("窗口3");
        station1.start();
        station2.start();
        station3.start();
View Code
 自己又写了一个方法上加同步的 感觉有点问题 ......你们也看一下吧
public class Station1 {
    private static String name;

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

    //synchronized的锁绑定在SynMethod.class上  (有点问题....第一之后一直第二)    感觉一般没人使用这种办法吧
    static int tick=1000;
    public static synchronized void sailTic()
    {
        while (tick>0)
        {

            System.out.println(name+"卖出了第"+tick+"张飘");
            tick--;
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("票已经卖完");
    }

}


-----------------
main函数请分开

 public static void main(String[] args) {

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//               // t1.sailTic();
//                Station1.setName("第一");
//                Station1.sailTic();
//
//            }
//        }).start();
//
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                Station1.setName("第二");
//                Station1.sailTic();
//            }
//        }).start();

        System.out.println("主线程完毕");

    }
View Code

窗口1卖完后 就一直窗口2卖 ........一直切换不到窗口1线程 ----任重道远

猜你喜欢

转载自www.cnblogs.com/xuexidememeda/p/12245153.html
今日推荐