标签:style turn 问题 冲突 ted ring 安全 必须 设置
单线程程序:处理流程始终一条线的程序。例如:无论是调用方法,还是执行for循环,if条件分支语句。甚至更复杂的处理,都不会对这条长线产生影响。在单线程程序中,“在某一时间点执行的处理”只有一个。“正在执行程序的主体”称为线程。
多线程程序:由多个线程组成的程序。例如:GUI应用程序,耗时的I/O处理,多个客户端。
并行:用于表示多个操作“同时处理”。
并发:用于表示“将一个操作分割成多个部分并且允许无序处理”。
启动线程的方法:(1)利用Thread类的子类的实例启动线程;eg:public class PrintThread extends Thread(2)利用Runnable接口的实现类的实例启动线程;eg:public class PrintThread implements Runnable
线程的互斥:synchronized,声明方法前加上关键字synchronized。加上可以确保该方法只能同时由一个线程执行。
临界区:只允许单个线程执行的程序范围。
何时使用synchronized:(1)多线程时 (2)多个线程访问时 (3)状态有可能发生改变时(4)需要确保安全性时
死锁:两个线程分别持有着锁,并且相互等待对方释放锁的现象。
死锁发生的条件:(1)存在多个SharedSource角色 (2)线程在持有某个SharedResource角色的锁的同时,还想获取其他SharedResource角色的锁(3)获取SharedResource角色的锁的顺序并不固定(SharedResource角色是对称的)PS:只要破坏其中一个条件就可以防止死锁发生。
线程冲突:当线程A执行临界区内的处理时,其他想要进入临界区的线程会阻塞。
线程要执行synchronized的实例方法,必须获取this的锁,而能够获取一个实例的锁的线程线程只有 一个。
原子操作:不可分割的操作。例如:执行synchronized方法的操作。
java基本类型(int和char)和对象引用类型的赋值和引用操作也是原子的。但是long和double类型的操作不是原子。long和double在线程间共享时,需要将其放入synchronized中操作,或者声明为volatile。
死锁问题:例如两人同吃一盘食物,要用刀和叉,只有同时拥有刀和叉才能吃饭,预防出现一人拿刀一人拿叉的情况出现,可以设置两人拿工具的顺序,都为刀-叉或都为叉-刀,或者只有同时拥有两个工具才能吃饭。设置顺序的代码如下:
1 public class PrintThread extends Thread{ 2 private String name; 3 private final Tool lefthand; 4 private final Tool righthand; 5 public PrintThread(String name,Tool lefthand,Tool righthand) { 6 this.name=name; 7 this.lefthand=lefthand; 8 this.righthand=righthand; 9 } 10 public void run() { 11 while(true) { 12 eat(); 13 } 14 } 15 public void eat() { 16 synchronized(lefthand) { 17 System.out.println(name+" takes up "+lefthand+"(left)."); 18 synchronized(righthand) { 19 System.out.println(name+" takes up "+righthand+"(left)."); 20 System.out.println(name+" is eating. "); 21 System.out.println(name+" puts down "+lefthand+"(left)."); 22 System.out.println(name+" puts down "+righthand+"(left)."); 23 } 24 } 25 } 26 public static class Tool{ 27 private final String name; 28 public Tool(String name) { 29 this.name=name; 30 } 31 public String toString() { 32 return "["+name+"]"; 33 } 34 } 35 36 //public class Main() { 37 public static void main(String[] args) { 38 Tool spoon=new Tool("spoon"); 39 Tool fork=new Tool("fork"); 40 new PrintThread("Alice",spoon,fork).start(); 41 new PrintThread("borry",spoon,fork).start(); 42 } 43 }
声明为final的类,无法创建子类。
延长临界区可以提高检查出错误的可能性,用sleep可以早点发现错误。
private字段只有在该类内部才可以访问;protected字段可以被该类的子类和同一个包内的类访问;public字段则可以被任何类访问。
java多线程(一)---Single Threaded Execution
标签:style turn 问题 冲突 ted ring 安全 必须 设置
原文地址:https://www.cnblogs.com/gtz-gdufs/p/12271582.html