标签:
package threaddemos; /* * 该类要重写run()方法,为什么呢? * 不是类中的所有代码都需要被线程执行的。 * 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。 */ public class MyThread extends Thread{ @Override public void run(){ for (int x = 0; x < 200; x++) { System.out.println(x); } } }
测试类:
package threaddemos; /** * Created by gao on 16-1-3. */ public class ThreadDemo01 { public static void main(String[] args) { // 创建线程对象 // MyThread my = new MyThread(); // // 启动线程 // my.run(); // my.run(); // 调用run()方法为什么是单线程的呢? // 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果 // 面试题:run()和start()的区别? // run():仅仅是封装被线程执行的代码,直接调用是普通方法 // start():首先启动了线程,然后再由jvm去调用该线程的run()方法。 // MyThread my = new MyThread(); // my.start(); // // IllegalThreadStateException:非法的线程状态异常 // // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。 // my.start(); // 创建两个线程对象 MyThread my1 = new MyThread(); MyThread my2 = new MyThread(); my1.start(); my2.start(); } }
package threaddemos; public class MyThread2 extends Thread { public MyThread2() { } public MyThread2(String name) { super(name); } @Override public void run() { for (int x = 0; x < 200; x++) { System.out.println(getName() + "---" + x); } } }
测试类:
package threaddemos; /** * Created by gao on 16-1-3. */ public class ThreadDemo02 { public static void main(String[] args) { // 创建线程对象 //无参构造+setXxx() // MyThread2 my1 = new MyThread2(); // MyThread2 my2 = new MyThread2(); // my1.setName("林青霞"); // my2.setName("刘意"); // my1.start(); // my2.start(); //带参构造方法给线程起名字 MyThread2 my1 = new MyThread2("林青霞"); MyThread2 my2 = new MyThread2("刘意"); my1.start(); my2.start(); //获取main方法所在的线程对象的名称 //public static Thread currentThread():返回当前正在执行的线程对象 System.out.println(Thread.currentThread().getName()); } } /* 名称为什么是:Thread-? 编号 class Thread { private char name[]; public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } private void init(ThreadGroup g, Runnable target, String name, long stackSize) { init(g, target, name, stackSize, null); } private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) { //大部分代码被省略了 this.name = name.toCharArray(); } public final void setName(String name) { this.name = name.toCharArray(); } private static int threadInitNumber; //0,1,2 private static synchronized int nextThreadNum() { return threadInitNumber++; //return 0,1 } public final String getName() { return String.valueOf(name); } } class MyThread extends Thread { public MyThread() { super(); } } */
package threaddemos; /** * Created by gao on 16-1-4. */ public class MyRunnable implements Runnable { @Override public void run() { for (int x = 0; x < 100; x++) { // 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用 System.out.println(Thread.currentThread().getName() + "---" + x); } } }
测试类:
package threaddemos; /** * Created by gao on 16-1-4. */ public class MyRunnableDemo { public static void main(String[] args) { // 创建MyRunnable类的对象 MyRunnable my = new MyRunnable(); // 创建Thread类的对象,并把C步骤的对象作为构造参数传递 // Thread(Runnable target) // Thread t1 = new Thread(my); // Thread t2 = new Thread(my); // t1.setName("林青霞"); // t2.setName("刘意"); // Thread(Runnable target, String name) Thread t1 = new Thread(my,"林青霞"); Thread t2 = new Thread(my,"刘意"); t1.start(); t2.start(); } }
3、线程调度和线程控制
1)线程调度
假如我们的计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到 CPU时间片,也就是使用权,才可以执行指令。那么Java是
如何对线程进行调用的呢?
线程有两种调度模型:
· 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片.
· 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
· Java使用的是抢占式调度模型。
2)设置和获取线程优先级
· public final int getPriority():返回线程的优先级。
· public final void setPriority(int newPriority):更改线程的优先级。
package threaddemos; /** * Created by gao on 16-1-4. */ /* * 我们的线程没有设置优先级,肯定有默认优先级。 * 获取线程对象的优先级 * public final int getPriority():返回线程对象的优先级 * 设置线程对象的优先级 * public final void setPriority(int newPriority):更改线程的优先级。 * * 注意: * 线程默认优先级是5。 * 线程优先级的范围是:1-10。 * 线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。 * * IllegalArgumentException:非法参数异常。 * 抛出的异常表明向方法传递了一个不合法或不正确的参数。 */ public class ThreadPriorityDemo01 { public static void main(String[] args) { ThreadPriority tp1 = new ThreadPriority(); ThreadPriority tp2 = new ThreadPriority(); ThreadPriority tp3 = new ThreadPriority(); tp1.setName("东方不败"); tp2.setName("岳不群"); tp3.setName("林平之"); // 获取默认优先级 // System.out.println(tp1.getPriority()); //5 // System.out.println(tp2.getPriority());//5 // System.out.println(tp3.getPriority());//5 // 设置线程优先级(范围出错) // tp1.setPriority(100000); //设置正确的线程优先级 tp1.setPriority(10); tp3.setPriority(1); tp1.start(); tp2.start(); tp3.start(); } }
package threaddemos; import java.util.Date; /** * Created by gao on 16-1-4. */ public class ThreadSleep extends Thread { public ThreadSleep() { } @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + "---" + x + "日期:" + new Date()); //睡眠,1秒钟 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
测试类:
package threaddemos; /** * Created by gao on 16-1-4. */ /* * 线程休眠 * public static void sleep(long millis) */ public class ThreadSleepDemo { public static void main(String[] args) { ThreadSleep ts1 = new ThreadSleep(); ThreadSleep ts2 = new ThreadSleep(); ThreadSleep ts3 = new ThreadSleep(); ts1.setName("林青霞"); ts2.setName("林志玲"); ts3.setName("林志颖"); ts1.start(); ts2.start(); ts3.start(); ts3.start(); } }
package cn.itcast_04; public class ThreadJoin extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); } } }
测试类:
package cn.itcast_04; /* * public final void join():等待该线程终止。 */ public class ThreadJoinDemo { 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(); } }
package cn.itcast_04; public class ThreadYield extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); Thread.yield(); } } }
测试类:
package cn.itcast_04; /* * public static void yield():暂停当前正在执行的线程对象,并执行其他线程。 * 让多个线程的执行更和谐,但是不能靠它保证一人一次。 */ public class ThreadYieldDemo { public static void main(String[] args) { ThreadYield ty1 = new ThreadYield(); ThreadYield ty2 = new ThreadYield(); ty1.setName("林青霞"); ty2.setName("刘意"); ty1.start(); ty2.start(); } }
例子4:
package cn.itcast_04; /* * public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。 * 当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。 * * 游戏:坦克大战。 */ public class ThreadDaemonDemo { public static void main(String[] args) { ThreadDaemon td1 = new ThreadDaemon(); ThreadDaemon td2 = new ThreadDaemon(); td1.setName("关羽"); td2.setName("张飞"); // 设置收获线程 td1.setDaemon(true); td2.setDaemon(true); td1.start(); td2.start(); Thread.currentThread().setName("刘备"); for (int x = 0; x < 5; x++) { System.out.println(Thread.currentThread().getName() + ":" + x); } } }
package cn.itcast_04; import java.util.Date; public class ThreadStop extends Thread { @Override public void run() { System.out.println("开始执行:" + new Date()); // 我要休息10秒钟,亲,不要打扰我哦 try { Thread.sleep(10000); } catch (InterruptedException e) { // e.printStackTrace(); System.out.println("线程被终止了"); } System.out.println("结束执行:" + new Date()); } }
测试类:
package cn.itcast_04; /* * public final void stop():让线程停止,过时了,但是还可以使用。 * public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。 */ public class ThreadStopDemo { public static void main(String[] args) { ThreadStop ts = new ThreadStop(); ts.start(); // 你超过三秒不醒过来,我就干死你 try { Thread.sleep(3000); // ts.stop(); ts.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } }
4、线程生命周期
package threaddemos; /** * Created by gao on 16-1-4. */ public class SellTicket extends Thread { // 定义100张票 // private int tickets = 100; // 为了让多个线程对象共享这100张票,我们其实应该用静态修饰 private static int tickets = 100; @Override public void run() { // 定义100张票 // 每个线程进来都会走这里,这样的话,每个线程对象相当于买的是自己的那100张票,这不合理,所以应该定义到外面 // int tickets = 100; // 是为了模拟一直有票 while (true) { if (tickets > 0) { System.out.println(getName() + "---" + "正在出售第" + (tickets--) + "张票"); } } } }
测试类:
package threaddemos; /** * Created by gao on 16-1-4. */ /* * 某电影院目前正在上映贺岁大片(红高粱,少林寺传奇藏经阁),共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。 * 继承Thread类来实现。 */ public class SellTicketDemo { public static void main(String[] args) { // 创建三个线程对象 SellTicket st1 = new SellTicket(); SellTicket st2 = new SellTicket(); SellTicket st3 = new SellTicket(); // 给线程对象起名字 st1.setName("窗口1"); st2.setName("窗口2"); st3.setName("窗口3"); // 启动线程 st1.start(); st2.start(); st3.start(); } }
2)方式二:实现Runnable接口
package threaddemos; /** * Created by gao on 16-1-4. */ public class SellTicket2 implements Runnable { private int tickets = 200; @Override public void run() { while (true) { if (tickets > 0) { System.out.println(Thread.currentThread().getName() + "---" + "正在出售第" + (tickets--) + "张票"); } } } }
测试类:
package threaddemos; /** * Created by gao on 16-1-4. */ /* * 实现Runnable接口的方式实现 */ public class SellTicketDemo2 { public static void main(String[] args) { // 创建资源对象 SellTicket2 st = new SellTicket2(); // 创建三个线程对象 Thread t1 = new Thread(st,"窗口1"); Thread t2 = new Thread(st,"窗口2"); Thread t3 = new Thread(st,"窗口3"); // 启动线程 t1.start(); t2.start(); t3.start(); } }
package threaddemos; /** * Created by gao on 16-1-4. */ public class SellTicket3 implements Runnable { // 定义100张票 private int tickets = 50; //创建锁对象 private Object obj = new Object(); @Override public void run() { while (true) { synchronized (obj) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票"); } } } } // @Override // public void run() { // // while (true) { // if (tickets > 0) { // System.out.println(Thread.currentThread().getName() + "---" + "正在出售第" + (tickets--) + "张票"); // } // } // } } 测试类: package threaddemos; /** * Created by gao on 16-1-4. */ /* * 实现Runnable接口的方式实现 */ public class SellTicketDemo3 { public static void main(String[] args) { // 创建资源对象 SellTicket3 st = new SellTicket3(); // 创建三个线程对象 Thread t1 = new Thread(st,"窗口1"); Thread t2 = new Thread(st,"窗口2"); Thread t3 = new Thread(st,"窗口3"); // 启动线程 t1.start(); t2.start(); t3.start(); } }
4)同步的特点
package threaddemos; /** * Created by gao on 16-1-4. */ public class SellTicket4 implements Runnable { // 定义100张票 private static int tickets = 100; // 定义同一把锁 private Object obj = new Object(); private Demo d = new Demo(); private int x = 0; //同步代码块用obj做锁 // @Override // public void run() { // while (true) { // synchronized (obj) { // if (tickets > 0) { // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } // System.out.println(Thread.currentThread().getName() // + "正在出售第" + (tickets--) + "张票 "); // } // } // } // } //同步代码块用任意对象做锁 // @Override // public void run() { // while (true) { // synchronized (d) { // if (tickets > 0) { // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } // System.out.println(Thread.currentThread().getName() // + "正在出售第" + (tickets--) + "张票 "); // } // } // } // } @Override public void run() { while (true) { if(x%2==0){ //加载class文件当锁 synchronized (SellTicket.class) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 "); } } }else { // synchronized (d) { // if (tickets > 0) { // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } // System.out.println(Thread.currentThread().getName() // + "正在出售第" + (tickets--) + "张票 "); // } // } sellTicket(); } x++; } } // private void sellTicket() { // synchronized (d) { // if (tickets > 0) { // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } // System.out.println(Thread.currentThread().getName() // + "正在出售第" + (tickets--) + "张票 "); // } // } // } //如果一个方法一进去就看到了代码被同步了,那么我就再想能不能把这个同步加在方法上呢? // private synchronized void sellTicket() { // if (tickets > 0) { // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } // System.out.println(Thread.currentThread().getName() // + "正在出售第" + (tickets--) + "张票 "); // } // } private static synchronized void sellTicket() { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 "); } } } class Demo { }
测试类:
package threaddemos; /** * Created by gao on 16-1-4. */ /* * 实现Runnable接口的方式实现 */ /* * A:同步代码块的锁对象是谁呢? * 任意对象。 * * B:同步方法的格式及锁对象问题? * 把同步关键字加在方法上。 * * 同步方法是谁呢? * this * * C:静态方法及锁对象问题? * 静态方法的锁对象是谁呢? * 类的字节码文件对象。 */ public class SellTicketDemo4 { public static void main(String[] args) { // 创建资源对象 SellTicket3 st = new SellTicket3(); // 创建三个线程对象 Thread t1 = new Thread(st,"窗口1"); Thread t2 = new Thread(st,"窗口2"); Thread t3 = new Thread(st,"窗口3"); // 启动线程 t1.start(); t2.start(); t3.start(); } }
6)以往的线程安全类
package cn.itcast_12; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; import java.util.List; import java.util.Vector; public class ThreadDemo { public static void main(String[] args) { // 线程安全的类 StringBuffer sb = new StringBuffer(); Vector<String> v = new Vector<String>(); Hashtable<String, String> h = new Hashtable<String, String>(); // Vector是线程安全的时候才去考虑使用的,但是不会用Vector,而是用下面的。 // public static <T> List<T> synchronizedList(List<T> list) List<String> list1 = new ArrayList<String>();// 线程不安全 List<String> list2 = Collections .synchronizedList(new ArrayList<String>()); // 线程安全 } }
标签:
原文地址:http://www.cnblogs.com/yangyquin/p/5098179.html