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 的前面的例子运行一下就明白很多) 这两种解决都可以 

也可以station 类继承Runnable 接口 实现run方法 加锁的时候直接this  主方法new 一个对象  开启两个线程 也不会出问题

买票main函数

 Station station1=new Station("窗口1");
        Station station2=new Station("窗口2");
        Station station3=new Station("窗口3");
        station1.start();
        station2.start();
        station3.start();
View Code

第二种写法 道理一样的 加锁那里写 this

public class Station1 implements  Runnable{
    static int tick=1000;
    @Override
    public void run() {

            while (tick>0)
            {

                synchronized (this)
                {
                    System.out.println(Thread.currentThread().getName()+"卖出了第"+tick+"张飘");
                    tick--;
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }



                }

        System.out.println("票已经卖完");

    }
}

  main

 Station1 station11=new Station1();
        Thread t1=new Thread(station11,"第一个");
        Thread t2=new Thread(station11,"第二个");
        t1.start();
        t2.start();
原文地址:https://www.cnblogs.com/xuexidememeda/p/12245153.html