p775 线程调度概述
java采用抢占式调度模型,根据线程的优先级来抢占。
p776 线程调度的方法(了解内容)
p777 线程优先级【代码说明】
package com.bjpowernode.java.thread;
public class ThreadTest11 {
public static void main(String[] args) {
// System.out.println("最高优先级"+Thread.MAX_PRIORITY);
// System.out.println("最低优先级"+Thread.MIN_PRIORITY);
// System.out.println("默认优先级"+Thread.NORM_PRIORITY);
//设置主线程优先级温为1
Thread.currentThread().setPriority(1);
//获取当前线程对象,获取当前线程的优先级
Thread currentThread = Thread.currentThread();
//System.out.println(currentThread.getName()+"线程的默认优先级是:"+currentThread.getPriority());
// MyRunnable5 myRunnable5 = new MyRunnable5();
// Thread t2 = new Thread(myRunnable5);
Thread t2 = new Thread(new MyRunnable5());
t2.setPriority(10);
t2.setName("ttt");
t2.start();
for (int i = 0; i < 100; i++) {
System.out.println("主线程---------->"+i);
}
//System.out.println(currentThread.getName()+"线程的优先级是:"+currentThread.getPriority());
}
}
class MyRunnable5 implements Runnable{
@Override
public void run() {
//获取线程优先级
for (int i = 0; i < 100; i++) {
System.out.println("分支线程---------->"+i);
}
//System.out.println(Thread.currentThread().getName() + "线程的默认优先级是:"+Thread.currentThread().getPriority());
}
}
p778 线程让位【静态方法yeild】
package com.bjpowernode.java.thread;
public class ThreadTest12 {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable6() );
t.setName("t2t");
t.start();
for (int i = 0; i <= 1000; i++) {
System.out.println(Thread.currentThread().getName()+"----》"+i);
}
}
}
class MyRunnable6 implements Runnable{
@Override
public void run() {
for (int i = 0; i <= 1000; i++) {
//每隔100让位1次
if (i % 100 == 0){
Thread.yield();//
}
System.out.println(Thread.currentThread().getName()+"----》"+i);
}
}
}
p779 线程合并【join()】
线程合并不是栈合并,只是发生了等待关系
package com.bjpowernode.java.thread;
public class THreadTest13 {
public static void main(String[] args) {
System.out.println("main begin!");
Thread t = new Thread(new MyRunnable7());
t.setName("t");
t.start();
//合并线程,t线程合并到当前线程中,当前线程受阻,执行t线程直到结束,才继续执行当前线程
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main over!");
}
}
class MyRunnable7 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName()+"------->"+i);
}
}
}
p780 线程安全是重点*****
p781 线程不安全的条件【多线程并发取钱取钱例子】
p782 怎么解决线程安全问题【线程排队执行】
使用线程排队解决线程安全问题,这种机制被叫做:线程同步机制。
p783 同步和异步的理解
p784 账户类的定义【模拟银行账户取款】
package com.bjpowernode.java.threadsafe;
public class Account {
private int no;
private double balance;
public Account() {
}
public Account(int no, double balance) {
this.no = no;
this.balance = balance;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//取款的方法
public void withdraw(double money){
//取款之前的余额
double before = this.getBalance();
//取款之后的余额
double after = before - money;
//更新余额
this.setBalance(after);
}
}
p785 模拟两个线程同时对一个银行账户操作
Account
package com.bjpowernode.java.threadsafe;
public class Account {
private int no;
private double balance;
public Account() {
}
public Account(int no, double balance) {
this.no = no;
this.balance = balance;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//取款的方法
public void withdraw(double money){
//取款之前的余额
double before = this.getBalance();
//取款之后的余额
double after = before - money;
//在这里模拟以下网络延迟,百分百出问题
try {
Thread.sleep(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//更新余额
this.setBalance(after);
}
}
AccountThread
package com.bjpowernode.java.threadsafe;
public class AccountThread extends Thread{
//两个线程必须共享同一个账户对象
private Account act;
//通过构造方法传递过来账户对象
public AccountThread(Account act) {
this.act = act;
}
public void run(){
//run方法表示取款操作
//假设取款5000
double money = 5000;
act.withdraw(money);
System.out.println(Thread.currentThread().getName()+"线程对账户"+ act.getNo() +"取款"+money+"成功,余额"+act.getBalance());
}
}
Test
package com.bjpowernode.java.threadsafe;
import com.sun.jdi.ThreadGroupReference;
public class Test {
public static void main(String[] args) {
//创建一个账户
Account act = new Account(123,10000.00);
//创建两个线程
Thread t1 = new AccountThread(act);
Thread t2 = new AccountThread(act);
//设置name
t1.setName("t1");
t2.setName("t2");
//启动线程取款
t1.start();
t2.start();
}
}
p786 同步代码块synchronized
p787 对synchronized的理解
p788 对synchronized的理解
p789 哪些变量有线程安全问题【重要】
p790 扩大同步范围
p791 synchronized出现在实例方法上
java中的变量分为:
成员变量【是指这个类的变量;;又分为静态变量【方法区】和实例变量【堆内存中】】
局部变量【在栈中】【方法体中的变量】
- java中的方法分为:
Java中的方法分为类方法和实例方法,区别是类方法中有static修饰,为静态方法,是类的方法。所以在类文件加载到内存时就已经创建,但是实例方法是对象的方法,只有对象创建后才起作用,所以在类方法中不能调用实例方法,但实例方法中可以调用类方法,且实例方法可以互相调用。
StringBuffer是线程安全的,StringBuilder是非线程安全的,如果是局部变量要使用,那就选择StringBuilder,因为效率更高,且不需要考虑线程安全问题。
ArrayList是非线程安全的
Vector是线程安全的
HashMap、HashSet是非线程安全的
HashTable是线程安全的
p792 synchronized的三种使用方法
类锁是为了保证静态变量的安全
p793 synchronized面试题1
package com.bjpowernode.java.exam;
public class exam01 {
public static void main(String[] args) throws InterruptedException {
Myclass mc = new Myclass();
Thread t1 = new Mythread(mc);
Thread t2 = new Mythread(mc);
t1.setName("t1");
t2.setName("t2");
t1.start();
t1.sleep(1000);
t2.start();
}
}
class Mythread extends Thread{
private Myclass mc;
public Mythread(Myclass mc) {
this.mc = mc;
}
public void run(){
if (Thread.currentThread().getName().equals("t1")){
mc.doSome();
}
if (Thread.currentThread().getName().equals("t2")){
mc.doOther();
}
}
}
class Myclass{
public synchronized void doSome(){
System.out.println("doSome begin");
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("doSome over");
}
public void doOther(){
System.out.println("doOther begin");
System.out.println("doOther over");
}
}
p794 synchronized面试题2
package com.bjpowernode.java.exam;
public class exam02 {
public static void main(String[] args) throws InterruptedException {
Myclass mc = new Myclass();
Thread t1 = new Mythread(mc);
Thread t2 = new Mythread(mc);
t1.setName("t1");
t2.setName("t2");
t1.start();
t1.sleep(1000);
t2.start();
}
}
class Mythread2 extends Thread{
private Myclass mc;
public Mythread2(Myclass mc) {
this.mc = mc;
}
public void run(){
if (Thread.currentThread().getName().equals("t1")){
mc.doSome();
}
if (Thread.currentThread().getName().equals("t2")){
mc.doOther();
}
}
}
class Myclass2{
public synchronized void doSome(){
System.out.println("doSome begin");
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("doSome over");
}
public synchronized void doOther(){
System.out.println("doOther begin");
System.out.println("doOther over");
}
}
p795 synchronized面试题3
package com.bjpowernode.java.exam;
public class exam03 {
public static void main(String[] args) throws InterruptedException {
Myclass mc1 = new Myclass();
Myclass mc2 = new Myclass();
Thread t1 = new Mythread(mc1);
Thread t2 = new Mythread(mc2);
t1.setName("t1");
t2.setName("t2");
t1.start();
t1.sleep(1000);
t2.start();
}
}
class Mythread3 extends Thread{
private Myclass mc;
public Mythread3(Myclass mc) {
this.mc = mc;
}
public void run(){
if (Thread.currentThread().getName().equals("t1")){
mc.doSome();
}
if (Thread.currentThread().getName().equals("t2")){
mc.doOther();
}
}
}
class Myclass3{
public synchronized void doSome(){
System.out.println("doSome begin");
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("doSome over");
}
public synchronized void doOther(){
System.out.println("doOther begin");
System.out.println("doOther over");
}
}
p796 synchronized面试题4
package com.bjpowernode.java.exam;
public class exam04 {
public static void main(String[] args) throws InterruptedException {
Myclass mc1 = new Myclass();
Myclass mc2 = new Myclass();
Thread t1 = new Mythread(mc1);
Thread t2 = new Mythread(mc2);
t1.setName("t1");
t2.setName("t2");
t1.start();
t1.sleep(1000);
t2.start();
}
}
class Mythread4 extends Thread{
private Myclass mc;
public Mythread4(Myclass mc) {
this.mc = mc;
}
public void run(){
if (Thread.currentThread().getName().equals("t1")){
mc.doSome();
}
if (Thread.currentThread().getName().equals("t2")){
mc.doOther();
}
}
}
class Myclass4{
public synchronized static void doSome(){
System.out.println("doSome begin");
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("doSome over");
}
public synchronized static void doOther(){
System.out.println("doOther begin");
System.out.println("doOther over");
}
}
p797 死锁概述
package com.bjpowernode.java.deadlock;
public class DeadLock {
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
//t1和t2两个线程共享o1和o2
MyThread1 t1 = new MyThread1(o1,o2);
MyThread1 t2 = new MyThread1(o1,o2);
t1.start();
t2.start();
}
}
class MyThread1 extends Thread{
Object o1;
Object o2;
public MyThread1(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
public void run(){
synchronized (o1){
try {
Thread.sleep(1000 * 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2){
}
}
}
}
class MyThread2 extends Thread{
Object o1;
Object o2;
public MyThread2(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
public void run(){
synchronized (o2){
try {
Thread.sleep(1000 * 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1){
}
}
}
}
synchronized在开发中不要嵌套使用