线程(一)

线程(一)

  注意:
     线程默认优先级是5
     线程优先级的范围是:1-10
     线程优先级高仅仅表示线程获取的CPU时间片的几率高,但是要在次数比较多,
    或者多次运行的时候才能看到比较好的效果

public class ThreadJoin extends Thread{
    @Override
    public void run() {
        for (int x=0;x<1000;x++){
            System.out.println(getName()+": "+x);
        }
    }
}
public static void main(String[] args) {
    ThreadJoin tj1=new ThreadJoin();
    ThreadJoin tj2=new ThreadJoin();
    ThreadJoin tj3=new ThreadJoin();
    tj1.setName("李渊");
    tj2.setName("李世民");
    tj3.setName("李治");
    tj1.start();
    try {
        // 该线程执行完, 其他线程才能开始抢占
        tj1.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    tj2.start();
    tj3.start();
}

礼让

public static void yield()暂停当前正在执行的线程对象,并执行其他线程。
让多个线程的执行更和谐,但不能靠它保证一人一次
public class ThreadYield extends Thread {
    @Override
    public void run() {
        for (int x=0;x<100;x++){
            System.out.println(getName()+": "+x);
            ThreadYield.yield();
        }
    }
}
public static void main(String[] args) {
    ThreadYield ty1=new ThreadYield();
    ThreadYield ty2=new ThreadYield();
    ty1.setName("西施");
    ty2.setName("萧太后");
    ty1.start();
    ty2.start();
}

/**
* public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。
* 当正在运行的线程都是守护线程时,Java 虚拟机退出. 该方法必须在启动线程前调用。
*
* 游戏: 坦克大战
* */
public class ThreadDaemon extends Thread{
    @Override
    public void run() {
        for (int x=0;x<100;x++){
            System.out.println(getName()+": "+x);
        }
    }
}
public static void main(String[] args) {
    ThreadDaemon td1 = new ThreadDaemon();
    ThreadDaemon ts2 = new ThreadDaemon();
    td1.setName("关羽");
    ts2.setName("张飞");
    //设置收获线程
    td1.setDaemon(true);
    ts2.setDaemon(true);
    td1.start();
    ts2.start();
    Thread.currentThread().setName("刘备");
    for (int x = 0; x < 5; x++) {
        System.out.println(Thread.currentThread().getName() + ": " + x);
    }
}

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int x=0;x<100;x++){
            //由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用
            System.out.println(Thread.currentThread().getName()+": "+x);
        }
    }
}
public static void main(String[] args) {
    //创建Runnable类的对象
    MyRunnable mr=new MyRunnable();

   //public Thread(Runnable target,tring name)
   Thread t1=new Thread(mr,"666");
   Thread t2=ew Thread(mr,"121");

    t1.start();
    t2.start();
}
如何解决线程安全问题呢?
   要想解决问题,就要知道哪些原因会导致出问题:
   A:是否是多线程环境
   B:是否是共享数据
  C:是否有多条语句操作共享数据
同步代码块:
      synchronized(对象){
           需要同步的代码;
      }
      注意:
           同步可以解决安全问题的根本原因就是在那个对象上,该对象如同锁的功能
         多个线程必须是同一把锁
/**
* 举例:
*      火车上上厕所
* 同步的特点:
*   前提: 多个线程
*   解决问题的时候要注意:多个线程使用的是同一锁对象
* 同步的好处
*   同步的出现解决了多线程的安全问题
* 同步的弊端
*   当线程相当多时,因为每个线程都回去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率
*
* */

/*
* A:同步代码块的锁对象是谁呢? 任意对象
* B:同步方法的格式及锁对象问题? 把同步关键字加在方法上
*       同步方法是谁呢? this
* c:静态方法及锁对象问题?
*   静态方法的锁对象是谁呢?
*       类的字节码文件对象。
* */
public class SellTicket implements Runnable {
    //定义100张票
    private int tickets=100;
    //创建锁对象
    private Object object=new Object();
    @Override
    public void run() {
        while (true){
            synchronized (object){
                if (tickets>0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
                }
            }
        }
    }
}

 

public class SellTicket implements Runnable{
    //定义100张票
    private int tickets=100;
    private int x=0;

    @Override
    public void run() {
        while (true) {
            if (x%2==0) {
                synchronized (this) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票");
                    }
                }
            } else {
                sellTicket();
            }
            x++;
        }
    }


    private  synchronized void sellTicket() {
        if(tickets > 0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票");
        }
    }

}
public class SellTicket implements Runnable{
    //定义100张票
    private static int tickets=100;
    private int x=0;
    @Override
    public void run() {
        while (true) {
            if (x%2==0) {
                synchronized (SellTicket.class) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票");
                    }
                }
            } else {
                sellTicket();
            }
            x++;
        }
    }
    private static synchronized void sellTicket() {
        if(tickets > 0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票");
        }
    }

}