标签:
多线程-同步的两种方式
一个储户,向两个账户存钱,每次存100,共存3次public class Demo {public static void main(String[] args) {Cus c = new Cus();//只为多个【线程】创建一个【线程任务】对象,否则同步是没有意义的new Thread(c, "第一个线程").start();new Thread(c, "第二个线程").start();}}class Bank {//银行账户private int sum;//账户1金额private int sum2;//账户2金额public synchronized void add(int num) {//同步函数,锁为this。若方法中有很多代码不需要同步,则使用同步函数会降低效率。sum = sum + num;try {Thread.sleep(10);} catch (InterruptedException e) {}System.out.println("账户1金额=" + sum);}public void add2(int num) {synchronized (this) {//同步代码块,锁可以为任意对象。因为可以使用同步代码块仅将需要同步的部分上锁,所以锁的范围比同步函数小,所以效率相对要高sum2 = sum2 + num;System.out.println(" 账户2金额=" + sum2);}}}//储户类,需多线程处理的行为是:向账户中存钱class Cus implements Runnable {private Bank b = new Bank();//银行账户public void run() {for (int x = 0; x < 3; x++) {b.add(100);//向账户1存钱b.add2(100);//向账户2存钱}}}账户1金额=100账户1金额=200账户2金额=100账户1金额=300账户2金额=200账户1金额=400账户2金额=300账户2金额=400账户1金额=500账户2金额=500账户1金额=600账户2金额=600
多线程-死锁-互锁
public class Demo {public static void main(String[] args) {System.out.println("开始");new Thread(new Test1(true)).start();new Thread(new Test1(false)).start();}}class Test1 implements Runnable {static private int num = 1;//设置为静态可以用来标记总执行次数private boolean flag;Test1(boolean flag) {//通过改变对象的状态值,来触发对象不同的代码块this.flag = flag;}static Object locka = new Object();static Object lockb = new Object();//为什么这两货一定要用静态修饰?因为,若是非静态的,则后面创建的两个Test1对象的此属性不是同一个对象,那么就无法同步,也不会有死锁发生public void run() {if (flag) {while (true)synchronized_logic1();} else {while (true)synchronized_logic2();}}private void synchronized_logic1() {synchronized (locka) {//先获得【a】锁System.out.println(Thread.currentThread().getName() + "..if a....执行次数" + num++);synchronized (lockb) {//再获得【b】锁(嵌套)System.out.println(Thread.currentThread().getName() + "..if b....执行次数" + num++);}try {Thread.sleep(1);//目的是让子弹飞一会} catch (InterruptedException e) {}}}private void synchronized_logic2() {synchronized (lockb) {//先获得【b】锁System.out.println(Thread.currentThread().getName() + "..else b....执行次数" + num++);synchronized (locka) {//再获得【a】锁(嵌套)System.out.println(Thread.currentThread().getName() + "..else a....执行次数" + num++);}try {Thread.sleep(1);//目的是让子弹飞一会} catch (InterruptedException e) {}}}}
多线程-死锁-嵌套
public class Demo {public static void main(String[] args) {Ticket2 t = new Ticket2();Thread t1 = new Thread(t);Thread t2 = new Thread(t);//这两个线程是同步的t1.start();//线程1启动,且启动后不会关闭try {Thread.sleep(100);//让子弹飞一会t.flag = false;//将状态改变,以便能启动线程2} catch (InterruptedException e) {e.printStackTrace();}t2.start();//线程2启动,且启动后不会关闭System.out.println("main线程已经执行完了--------------------");}}class Ticket2 implements Runnable {private int num;private Object obj = new Object();public boolean flag = true;//设置一个状态,以便能通过改变这个状态来触发方法public void run() {if (flag) {while (true) {synchronized (obj) {//请求获得obj锁show();//请求获得this锁}}} else {while (true) {show();}}}public synchronized void show() {synchronized (obj) {//请求获得obj锁System.out.println("当停止输出时,说明死锁发生了--" + num++ + "--" + flag);}}}
Thread 线程类API
构造方法
- Thread() 分配新的 Thread 对象
- Thread(Runnable target) 分配新的 Thread 对象
- Thread(Runnable target, String name) 分配新的 Thread 对象
- Thread(String name) 分配新的 Thread 对象
- Thread(ThreadGroup group, Runnable target) 分配新的 Thread 对象
- Thread(ThreadGroup group, Runnable target, String name) 分配新的 Thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,并作为 group 所引用的线程组的一员
- Thread(ThreadGroup group, Runnable target, String name, long stackSize) 分配新的 Thread 对象,将target作为其运行对象,将name作为其名称,作为group所引用的线程组的一员,并具有指定的堆栈大小
- Thread(ThreadGroup group, String name) 分配新的 Thread 对象
变量&常量
- static int MAX_PRIORITY 线程可以具有的最高优先级。
- static int MIN_PRIORITY 线程可以具有的最低优先级。
- static int NORM_PRIORITY 分配给线程的默认优先级。
公共方法
- static int activeCount() 返回当前线程的线程组中活动线程的数目。
- void checkAccess() 判定当前运行的线程是否有权修改该线程。
- int countStackFrames() 已过时。
- static Thread currentThread() 返回对当前正在执行的线程对象的引用。
- void destroy() 已过时。
- static void dumpStack() 将当前线程的堆栈跟踪打印至标准错误流。
- static int enumerate(Thread[] tarray) 将当前线程的线程组及其子组中的活动线程复制到数组中。
- static Map getAllStackTraces() 返回所有活动线程的堆栈跟踪的一个映射。
- ClassLoader getContextClassLoader() 返回该线程的上下文 ClassLoader。
- static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() 返回线程由于未捕获到异常而突然终止时调用的默认处理程序。
- long getId() 返回该线程的标识符。
- String getName() 返回该线程的名称。
- int getPriority() 返回线程的优先级。
- StackTraceElement[] getStackTrace() 返回一个表示该线程堆栈转储的堆栈跟踪元素数组。
- Thread.State getState() 返回该线程的状态。
- ThreadGroup getThreadGroup() 返回该线程所属的线程组。
- Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() 返回该线程由于未捕获到异常而突然终止时调用的处理程序。
- static boolean holdsLock(Object obj) 当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
- void interrupt() 中断线程。
- static boolean interrupted() 测试当前线程是否已经中断。
- boolean isAlive() 测试线程是否处于活动状态。
- boolean isDaemon() 测试该线程是否为守护线程。
- boolean isInterrupted() 测试线程是否已经中断。
- void join() 等待该线程终止。这名字好JB奇葩啊!
- void join(long millis) 等待该线程终止的时间最长为 millis 毫秒。
- void join(long millis, int nanos) 等待该线程终止的时间最长为 millis 毫秒+nanos 纳秒
- void resume() 已过时。
- void run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
- void setContextClassLoader(ClassLoader cl) 设置该线程的上下文 ClassLoader。
- void setDaemon(boolean on) 将该线程标记为守护线程或用户线程,当正在运行的线程都是守护线程是,Java虚拟机退出。该方法必须在启动线程前使用。
- static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序
- void setName(String name) 改变线程名称,使之与参数 name 相同。
- void setPriority(int newPriority) 更改线程的优先级。
- void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 设置该线程由于未捕获到异常而突然终止时调用的处理程序。
- static void sleep(long millis) 在指定的毫秒数内让【当前】正在执行的线程休眠
- static void sleep(long millis, int nanos) 在指定的毫秒数+纳秒数内让当前正在执行的线程休眠
- void start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
- void stop() 已过时。
- void stop(Throwable obj) 已过时。
- void suspend() 已过时。
- String toString() 返回该线程的字符串表示形式,包括线程名称、优先级和线程组。
- static void yield() 暂停当前正在执行的线程对象,并执行其他线程。
标签:
原文地址:http://www.cnblogs.com/baiqiantao/p/5451819.html