多线程(二)
七、获取线程名字和设置名字
* 1.获取名字
* 通过getName()方法获取线程对象的名字
* 2.通过构造函数可以传入String类型的名字
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
new
Thread(
"xxx"
) { public void run() { for ( int i = 0 ; i < 1000 ; i++) { System.out.println( this .getName() + "....aaaaaaaaaaaaaaaaaaaaaaa" ); } } }.start(); new Thread( "yyy" ) { public void run() { for ( int i = 0 ; i < 1000 ; i++) { System.out.println( this .getName() + "....bb" ); } } }.start(); |
* 3.通过setName(String)方法可以设置线程对象的名字
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Thread t1 =
new
Thread() { public void run() { for ( int i = 0 ; i < 1000 ; i++) { System.out.println( this .getName() + "....aaaaaaaaaaaaaaaaaaaaaaa" ); } } }; Thread t2 = new Thread() { public void run() { for ( int i = 0 ; i < 1000 ; i++) { System.out.println( this .getName() + "....bb" ); } } }; t1.setName( "线程1" ); t2.setName( "线程2" ); t1.start(); t2.start(); |
八、获取当前线程对象
Java Code
1
2 3 4 5 6 7 8 9 |
new
Thread(
new
Runnable() { public void run() { for ( int i = 0 ; i < 1000 ; i++) { System.out.println(Thread.currentThread().getName() + "...bb" ); } } }).start(); Thread.currentThread().setName( "我是主线程" ); //获取主函数线程的引用,并改名字 System.out.println(Thread.currentThread().getName()); //获取主函数线程的引用,并获取名字 |
九、休眠线程、守护线程、加入线程
1,Thread.sleep(毫秒,纳秒), 控制当前线程休眠若干毫秒1秒= 1000毫秒 1秒 = 1000 * 1000 * 1000纳秒 1000000000
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 |
new
Thread() { public void run() { for ( int i = 0 ; i < 10 ; i++) { System.out.println(getName() + "...bb" ); try { Thread.sleep( 10 ); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); |
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Thread t1 =
new
Thread() { public void run() { for ( int i = 0 ; i < 50 ; i++) { System.out.println(getName() + "...aaaaaaaaaaaaaaaaaaaaaa" ); try { Thread.sleep( 10 ); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread t2 = new Thread() { public void run() { for ( int i = 0 ; i < 5 ; i++) { System.out.println(getName() + "...bb" ); try { Thread.sleep( 10 ); } catch (InterruptedException e) { e.printStackTrace(); } } } }; t1.setDaemon(true); //将t1设置为守护线程 t1.start(); t2.start(); |
3, join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续,join(int), 可以等待指定的毫秒之后继续
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Thread t2 =
new
Thread() { public void run() { for ( int i = 0 ; i < 50 ; i++) { if (i == 2 ) { try { //t1.join(); //插队,加入 t1.join( 30 ); //加入,有固定的时间,过了固定时间,继续交替执行 Thread.sleep( 10 ); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(getName() + "...bb" ); } } }; t1.start(); t2.start(); |
十、同步代码块与同步方法
* 1.什么情况下需要同步
* 当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步.
* 如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码.
* 2.同步代码块
* 使用synchronized关键字加上一个锁对象来定义一段代码, 这就叫同步代码块
* 多个同步代码块如果使用相同的锁对象, 那么他们就是同步的
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class
Printer { Demo d = new Demo(); public static void print1() { synchronized (d){ //锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象 System.out.print( "北" ); System.out.print( "京" ); System.out.print( "烤" ); System.out.print( "鸭" ); System.out.print( "\r\n" ); } } public static void print2() { synchronized (d){ System.out.print( "宫" ); System.out.print( "保" ); System.out.print( "鸡" ); System.out.print( "丁" ); System.out.print( "\r\n" ); } } } |
* 3.使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class
Printer { public static void print1() { synchronized (Printer. class ){ //锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象 System.out.print( "北" ); System.out.print( "京" ); System.out.print( "烤" ); System.out.print( "鸭" ); System.out.print( "\r\n" ); } } /* * 非静态同步函数的锁是:this * 静态的同步函数的锁是:字节码对象 */ public static synchronized void print2() { System.out.print( "宫" ); System.out.print( "保" ); System.out.print( "鸡" ); System.out.print( "丁" ); System.out.print( "\r\n" ); } } |
十一、多线程安全问题
* 多线程并发操作同一数据时, 就有可能出现线程安全问题
* 使用同步技术可以解决这种问题, 把操作数据的代码进行同步, 不要多个线程一起操作
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
public
class
Demo2_Synchronized { /** * @param args * 需求:铁路售票,一共100张,通过四个窗口卖完. */ public static void main( String [] args) { TicketsSeller t1 = new TicketsSeller(); TicketsSeller t2 = new TicketsSeller(); TicketsSeller t3 = new TicketsSeller(); TicketsSeller t4 = new TicketsSeller(); t1.setName( "窗口1" ); t2.setName( "窗口2" ); t3.setName( "窗口3" ); t4.setName( "窗口4" ); t1.start(); t2.start(); t3.start(); t4.start(); } } class TicketsSeller extends Thread { private static int tickets = 100 ; static Object obj = new Object(); public TicketsSeller() { super (); } public TicketsSeller( String name) { super (name); } public void run() { while (true) { synchronized (obj) { if (tickets <= 0 ) break ; try { Thread.sleep( 10 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + "...这是第" + tickets-- + "号票" ); } } } } |