线程(一)
注意: 线程默认优先级是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--) + "张票"); } } }