java 多线程
java多线程的笔记
java线程有两种书写形式:
1.继承实现(不推荐1.单继承 <java中只有单继承> 2.只能实例化一次 无法多次使用)
class mythread extends Thread{ /* * 继承实现 (不推荐1.单继承2.无法多次使用) */ @Override public void run() { for(int i=0;i<50;i++) //Thread.currentThread().getName()得到当前线程 System.out.println(Thread.currentThread().getName()+"-"+i); try { Thread.sleep(500); //休眠 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2.接口实现(推荐)
class myrunnable1 implements Runnable{ /* *利用接口实现 (推荐) */ @Override public void run() { for(int i=0;i<50;i++) System.out.println(Thread.currentThread().getName()+"-"+i); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
补充:
调用thread下的start方法 即表示开始线程操作
Thread.sleep(500); 休眠毫秒数 (给其他线程使用cpu)需要try-catch
Thread.currentThread() 得到当前线程
==========================================================
插队线程
join()方法让调用的线程先执行指定时间或执行完毕
中断线程
(1)使用interrupt方法来中断线程,设置一个中断状态
(2)自定义标记(推荐使用)
此为interrupt和join方法示例
public class ThreadDemo2 { public static void main(String[] args) { myrunnable my=new myrunnable(); Thread t=new Thread(my); t.start(); for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName()+"-"+i); if(i==20) { try { t.join(); //让线程执行完毕 } catch (InterruptedException e) { e.printStackTrace(); } t.interrupt(); //中断线程,只是做了一个中断标记 } try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class myrunnable implements Runnable{ /* * 覆盖了父类线程的run函数 */ @Override public void run() { for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName()+"-"+i); if(Thread.interrupted()) { //测试中断状态,此方法将中断状态清除 break; } try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); Thread.currentThread().interrupt(); } } } }
此为自定义标记-flag为自定义标记若被改变即停止线程操作
public class ThreadDemo2 { public static void main(String[] args) { mythread2 my2=new mythread2(); Thread t2=new Thread(my2); t2.start(); for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName()+"-"+i); if(i==20) { my2.flag=false; } } } class mythread2 implements Runnable{ public boolean flag=true; int i=0; @Override public void run() { while(flag) { System.out.println(Thread.currentThread().getName()+"-"+i); i++; } } } }
守护线程
1.线程可以分成守护线程和用户线程,当进程中没用用户线程 ,会退出
2.实例:线程.setDemo(true)
======================================================================
同步线程
保证在一个线程运行时(对其上锁),其他线程不能访问此同步的线程
* 特点:
* 1.多线程共享数据时会发生线程不安全的情况
* 2.多线程共享数据必须同步但会牺牲新能
* 同步线程实现方法:
* 1.synchronized
* 2.将①独立成方法
* 3.lock(更灵活)
示例
class runanle implements Runnable{ private int count=10; @Override public void run() { while( true) { if(count<=0) break; synchronized (this) { //调用自带锁 count--; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("倒计时"+this+count); } } } }
补充:
synchronized (this) //this指调用当前函数自带锁,也可自行定义类型锁
//lock实现同步 ReentrantLock lock=new ReentrantLock(); public void method() { lock.lock(); //锁 lock.unlock(); //解锁 }
ReentrantLock lock=new ReentrantLock();必须在类外先实例化锁后
在定义函数时 调用lock加锁 unlock解锁
主函数调用
public class 同步线程 { public static void main(String[] args) { runanle r1=new runanle(); Thread t1=new Thread(r1); Thread t2=new Thread(r1); t1.start(); t2.start(); } }
注意:线程定义实例只在同一个函数下!
runanle r1=new runanle();
Thread t1=new Thread(r1);
Thread t2=new Thread(r1);