class primeTHread extends Thread {
public void run(){
// run 方法线程体 ... }
}
public static void main (String [] args) { // 创建线程对象
primeTHread t = new primeTHread ();
t.start();
}
public class TestThrread3 implements Runnable { public void run(){ } public static void main(String [] args) { // 创建runnable接口的实现类对象 TestThread3 testThread3 = new TestTrhread3(); Thread t1 = new Thread(testThread3 ); t1.start(); } }
推荐使用实现runnable接口方式创建线程
多个线程同时操作一个数据会造成
可以定义返回值,可以抛出异常
public class TestThrread4 implements callable<Boolean>{ public Boolean call() { return true; } public static void main(String [] args) { // 创建runnable接口的实现类对象 TestThread4 t4= new TestTrhread4(); //创建执行服务: ExecutorService ser = Executors.newFixedThreadPool(1); // 提交执行 Future<Boolean> r1 = ser.submit(t4) // 获取结果 boolean rs1 = r1.get(); // 关闭服务 ser.shutdownNow(); } }
public class TestThread1 implements Runnable{ private int ticketNum = 10; @Override public void run(){ while(true) { if (ticketNum<=0) { break; } System.out.println(Thread.currentThread().getName() +"----get----"+ ticketNum +"---ticket---"); try{ Thread.sleep(200); }catch(Exception e){ System.out.println("error"); } ticketNum--; } } public static void main(String [] args) { TestThread1 t1 = new TestThread1(); new Thread(t1,"jack").start(); new Thread(t1,"roll").start(); new Thread(t1,"marry").start(); } }
多线程操作会发生异常,同一份数据被多个人使用了。
Thread 的底层原理也是静态代理模式
真实对象和目标代理兑现都要实现同一个接口。代理对象要代理真实角色。真实对象专注做自己的事情,代理对象则负责帮忙处理其他事情。
package staticProxy; public class Person implements Marry{ @Override public void happyWedding() { System.out.println("xxx结婚"); } }
package staticProxy; public class StaticProxy { public static void main(String[] args) { WeddingCompany wc = new WeddingCompany(new Person()); wc.happyWedding(); } }
package staticProxy; public class WeddingCompany implements Marry{ Person person; public WeddingCompany(Person person) { this.person = person; } @Override public void happyWedding() { before(); person.happyWedding(); after(); } private void after() { System.out.println("结账"); } private void before() { System.out.println("布置婚礼"); } }
package staticProxy; public interface Marry { void happyWedding(); }
运行结果:
可以避免匿名内部类定义过多,让代码变得很简洁。去掉了没有意义的代码,只留下核心代码。
任何接口只包含唯一一个抽象方法,name他就是函数式的接口。
package lambda; public class testLambda { public static void main(String[] args) { like l = (int a)-> { System.out.println(a + "喜欢钱"); }; l.iLike(1); } } interface like{ void iLike(int a); }
setPriority(int newPriority) | 更改线程的优先级。 |
static void sleep(long millis) | 在指定毫秒数让当前执行的线程休眠 |
void join | 等待该线程终止。 |
static void yield() | 暂停当前正在执行的线程,并执行其他线程。 |
void interrupt | 中断线程,最好别用。 |
boolean isAlive() | 测试线程是否活动状态 |
不推荐使用stop()、destroy()方法。推荐线程自己停止。使用标志位终止变量。
package thread; public class testStop implements Runnable{ private boolean flag = true; @Override public void run() { int i = 0; while (flag) { System.out.println("run 线程运行中--" + i++); } } public void stop() { this.flag = false; } public static void main(String[] args) { testStop t1 = new testStop(); new Thread(t1).start(); for (int j = 0; j < 120; j++) { System.out.println("main线程运行中--" +j); if (j == 100) { t1.stop(); System.out.println("run停止"); } } } }
Thread.sleep(1000);
每个对象都有一个锁,sleep不会释放锁;
sleep可以模拟网络延时,倒计时等。
sleep时间到达之后线程进入就绪状态。
sleep存在异常InterruptedException;
Thread.yield ();
让当前正在执行的线程暂停,但不阻塞。
让线程从运行状态转为就绪状态
线程让步不一定成功。
可以想象成vip插队,等待此线程执行完成之后再执行其他线程,其他线程阻塞。
getPriority()
setPriority(int xxx)
设置线程优先级并不能百分百保证优先执行,只是提高概率。
要先设置优先级再执行
线程分为用户线程和守护线程
虚拟机必须确保用户线程执行完毕
虚拟机不用等待守护线程执行完毕
如:后台记录操作日志,监控内存,垃圾回收等待...
package thread; public class Testdaemon { public static void main(String[] args) { user u = new user(); damon d = new damon(); Thread t1 = new Thread(d); t1.setDaemon(true); t1.start(); Thread t2 = new Thread(u); t2.start(); } } class user implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("----user----"); } } } class damon implements Runnable{ @Override public void run() { while (true) { System.out.println("----damon----"); } } }
用户线程结束后,守护线程执行自动停止。
synchronzied
防止并发状况下保证数据在方法中被访问时的正确性,加入锁机制 synchronzied。
必须拿到锁之后才能执行,否则就会阻塞。
同步方法的弊端:会影响性能
package thread; public class Sync implements Runnable{ private int ticketNum = 10; private boolean flag = true; @Override public void run() { while (flag) { try { buy(); } catch (InterruptedException e) { e.printStackTrace(); } } } // 锁的是this public synchronized void buy() throws InterruptedException { if(ticketNum <= 0) { flag = false; return; } Thread.sleep(100); System.out.println(Thread.currentThread().getName() + "拿到了" + ticketNum--); } public static void main(String[] args) { Sync s = new Sync(); new Thread(s,"张三").start(); new Thread(s,"李四").start(); new Thread(s,"王二麻子").start(); } } 执行结果 张三拿到了10 王二麻子拿到了9 李四拿到了8 李四拿到了7 王二麻子拿到了6 张三拿到了5 王二麻子拿到了4 李四拿到了3 王二麻子拿到了2 张三拿到了1
产生死锁的四个必要条件:
互斥条件:一个资源每次只能被一个进程使用。
请求与保持条件:一个进程因为请求资源而阻塞时,对已获得的资源不放。
不剥夺条件:进程已获得资源,在未使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
package thread; public class testDeadlock { public static void main(String[] args) { fangbian f = new fangbian(0,"张三"); fangbian b = new fangbian(1,"李四"); new Thread(f).start(); new Thread(b).start(); } } class fangbian implements Runnable{ static wc w = new wc(); static paper p = new paper(); int chioce; //顺序不同,有人选择先拿纸进wc 有人选择先进再拿纸 String name; public fangbian(int chioce, String name) { this.chioce = chioce; this.name = name; } public void run() { if (chioce == 0) { synchronized (p) { System.out.println(name + "拿纸"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (w) { System.out.println(name +"进入wc"); } } else { synchronized (w) { System.out.println(name +"进入wc"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (p) { System.out.println(name +"拿纸"); } } } } class wc { } class paper { }
运行结果:
张三拿纸 李四进入wc 张三进入wc 李四拿纸
lock 是显示的锁,需要手动开启和关闭。synchronized 是隐藏的锁,出了作用域就自动释放。
lock只有代码块锁,synchronized 可以锁方法也可以锁代码块。
lock具有更好性能和更高的扩展性。有很多子类。
使用优先顺序:lock > 同步代码块(已经进入方法,分配相对应的资源)> 同步方法 (在方法之外)
package thread; public class testDeadlock { public static void main(String[] args) { fangbian f = new fangbian(0,"张三"); fangbian b = new fangbian(1,"李四"); new Thread(f).start(); new Thread(b).start(); } } class fangbian implements Runnable{ static wc w = new wc(); static paper p = new paper(); int chioce; String name; public fangbian(int chioce, String name) { this.chioce = chioce; this.name = name; } public void run() { if (chioce == 0) { synchronized (p) { System.out.println(name + "拿纸"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (w) { System.out.println(name +"进入wc"); } } else { synchronized (w) { System.out.println(name +"进入wc"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (p) { System.out.println(name +"拿纸"); } } } } class wc { } class paper { }
生产者和消费者之后互相通信。
原文:https://www.cnblogs.com/daylight9547/p/14649044.html