一.多线程
public class TestThread extends Thread{
@Override
public void run() {
System.out.println("多线程运行代码");
for (int i=0;i<5;i++){
System.out.println("多线程的逻辑代码"+i);
}
}
}
public class Test {
public static void main(String[] args) {
Thread t0=new TestThread();
t0.start();//启动线程
System.out.println("=============1");
System.out.println("=============2");
System.out.println("=============3");
}
}
测试输出
创建线程的两种方式
public class TestRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"Runnable多线程运行代码");
for (int i=0;i<5;i++){
System.out.println("Runnable多线程的逻辑代码"+i);
}
}
}
Thread t3=new Thread(new TestRunnable() ); t3.start(); Thread t4=new Thread(new TestRunnable() ,"t-1"); t4.start(); Thread t5=new Thread(new TestRunnable() ,"t-2"); t5.start();
继承方式和实现方式的联系
使用多线程的优点
1.提高应用程序的响应,对图形化界面更有意义,可增强用户体验。
2.提高计算机系统cpu的利用率
3.改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
Thread类的有关方法
public class Test1 {
public static void main(String[] args) {
TestRun run0=new TestRun();
TestRun run1=new TestRun();
Thread t0=new Thread(run0);
Thread t1=new Thread(run1);
// t0.setName("线程t0");//设置线程名称
t0.start();
t1.start();
System.out.println(t0.getName());//如果在创建线程的时候没有指定的名称,系统就会给出默认名称
// 通过 .getName()获取名称
System.out.println(t1.getName());
System.out.println("=============1");
System.out.println("=============2");
System.out.println("=============3");
}
}
class TestRun implements Runnable{
int count=0;
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"Runnable多线程运行代码");
for (int i=0;i<5;i++){
System.out.println("Runnable多线程的逻辑代码"+i);
}
}
}
线程的优先级(优先级代表被执行概率大小)
在Test1里面作下面改写
t0.setName("线程t-0");//设置线程名称
t1.setName("线程t-1");//设置线程名称
t0.setPriority(1);//设置线程的优先级
t1.setPriority(10);
t0.start();
t1.start();
System.out.println(t0.getName());//如果在创建线程的时候没有指定的名称,系统就会给出默认名称
// 通过 .getName()获取名称
System.out.println(t1.getName());
System.out.println("t0的优先级:"+t0.getPriority());//获取线程的优先级
System.out.println("=============1");
System.out.println("=============2");
System.out.println("=============3");
}
线程让步
if (i%2==0){
Thread.yield();//线程让步
}
t0.join();//相当于把run的代码插入到这个位置执行,执行是同步的 // t0的执行总是在2和3之间
Thread.sleep(1000);//当前线程睡眠1000毫秒打印延迟
t1.stop();//强制线程生命期结束
System.out.println(t1.isAlive());//判断线程是否活着
二。线程的生命周期(新建 就绪 运行 阻塞 死亡)
三。线程的同步
public class Test2 {
public static void main(String[] args) {
//定义账户对象
Acount a=new Acount();
Acount a1=new Acount();
//多线程对象
User u_weixin=new User(a,2000);
User u_zhifubao=new User(a1,2000);
Thread weixin=new Thread(u_weixin,"微信");
Thread zhifubao=new Thread(u_zhifubao,"支付宝");
weixin.start();
zhifubao.start();
}
}
class Acount{
public static int money=3000;//全局变量
//提款 判断账户钱够不够
// 多线程调用这个方法,就有问题,线程共享资源时一个线程在执行这个方法另一个线程又开始执行这个方法
// 解决思路:显然一个线程整体执行完这个方法,另一个线程再执行
//通过synchronized同步锁来完成(直接加在方法上)锁的是整个的对象,不是某一个方法
// 不同的对象就是不同的锁,普通方法加synchronized,县城使用不同此方法的对象
public synchronized void drawing(int m){
String name=Thread.currentThread().getName();
if (money < m) {
System.out.println(name+"操作,账户金额不足"+ money);
}else{
System.out.println(name+"操作,账户原有金额"+ money);
System.out.println(name+"操作,取款金额"+ m);
money=money-m;
System.out.println(name+"操作,取款后的金额"+ money);
}}
public synchronized void drawing1(int m){
String name=Thread.currentThread().getName();
if (money < m) {
System.out.println(name+"操作,账户金额不足"+ money);
}else{
System.out.println(name+"操作,账户原有金额"+ money);
System.out.println(name+"操作,取款金额"+ m);
money=money-m;
System.out.println(name+"操作,取款后的金额"+ money);
}}
//静态的方法加synchronized对于所有的对象都是同一个锁
public static synchronized void drawing2(int m){
String name=Thread.currentThread().getName();
if (money < m) {
System.out.println(name+"操作,账户金额不足"+ money);
}else{
System.out.println(name+"操作,账户原有金额"+ money);
System.out.println(name+"操作,取款金额"+ m);
money=money-m;
System.out.println(name+"操作,取款后的金额"+ money);
}}
public void drawing3(int m){
synchronized(this){//表示当前对象的代码块被加了同步锁
//用this锁代码块是代表当前的对象,如果在其他方法中也有这样的方法
String name=Thread.currentThread().getName();
if (money < m) {
System.out.println(name+"操作,账户金额不足"+ money);
}else{
System.out.println(name+"操作,账户原有金额"+ money);
System.out.println(name+"操作,取款金额"+ m);
money=money-m;
System.out.println(name+"操作,取款后的金额"+ money);
}}}
public void drawing4(int m){
synchronized(this){//表示当前对象的代码块被加了同步锁
//用this锁代码块是代表当前的对象,如果在其他方法中也有这样的方法
String name=Thread.currentThread().getName();
if (money < m) {
System.out.println(name+"操作,账户金额不足"+ money);
}else{
System.out.println(name+"操作,账户原有金额"+ money);
System.out.println(name+"操作,取款金额"+ m);
money=money-m;
System.out.println(name+"操作,取款后的金额"+ money);
}}}
//修饰代码块,想要根据不同的对象和不同的锁
public void drawing5(int m,Acount a){
synchronized(a){//表示通过方法参数传递进来的对象当前对象的代码块被加了同步锁
//不同的方法不同的同步锁
String name=Thread.currentThread().getName();
if (money < m) {
System.out.println(name+"操作,账户金额不足"+ money);
}else{
System.out.println(name+"操作,账户原有金额"+ money);
System.out.println(name+"操作,取款金额"+ m);
money=money-m;
System.out.println(name+"操作,取款后的金额"+ money);
}}}
}
class User implements Runnable{
Acount aount;
int money;
public User(Acount aount,int money){
this.aount=aount;
this.money=money;
}
@Override
public void run() {
// aount.drawing(money);
if (Thread.currentThread().getName().equals("微信")){
// aount.drawing(money);
// }else {
// aount.drawing1(money);
}
aount.drawing2(money);//调用类的静态
aount.drawing3(money);
aount.drawing5(money,aount);
}
}
线程的通信
public void drawing5(int m,Acount a){
synchronized(a){//表示通过方法参数传递进来的对象当前对象的代码块被加了同步锁
//不同的方法不同的同步锁
String name=Thread.currentThread().getName();
//如果是微信操作,先不执行,等待支付宝操作,支付宝操作完,微信再继续操作
if(name.equals("微信")){
try {
a.wait();//当前的线程进入等待的阻塞状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (money < m) {
System.out.println(name+"操作,账户金额不足"+ money);
}else{
System.out.println(name+"操作,账户原有金额"+ money);
System.out.println(name+"操作,取款金额"+ m);
money=money-m;
System.out.println(name+"操作,取款后的金额"+ money);
} if(name.equals("支付宝")){
try {
a.notify();//唤醒当前优先级,进入就绪状态
a.notifyAll();//唤醒当前所有线程,进入就绪状态
} catch (Exception e) {
e.printStackTrace();
}
}
}}
}
class User implements Runnable{
Acount aount;
int money;
public User(Acount aount,int money){
this.aount=aount;
this.money=money;
}
@Override
public void run() {
// aount.drawing(money);
if (Thread.currentThread().getName().equals("微信")){
// aount.drawing(money);
// }else {
// aount.drawing1(money);
}
aount.drawing2(money);//调用类的静态
aount.drawing3(money);
aount.drawing5(money,aount);
}
}
生产者消费者问题
package hellojava.day15;
//生产者与消费者
public class Test3 {
public static void main(String[] args) {
Clerk c=new Clerk();
//消费时不生产,生产时不消费
//生产者
new Thread(new Runnable() {
@Override
public void run() {
synchronized (c){
while (true){//无限循环代表无限的生产次数
if (c.productNum==0){//产品为零开始生产
System.out.println("产品数为零,开始生产");
while (c.productNum<4){
c.productNum++;//增加产品
System.out.println("库存"+c.productNum);
}
System.out.println("产品数"+c.productNum+"生产结束");
c.notify();//唤醒消费者
}else {
try {
c.wait();//生产者线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
},"生产者").start();
//消费者
new Thread(new Runnable() {
@Override
public void run() {
synchronized (c){
while (true){//无限循环代表无限的消费次数
if (c.productNum==4){//产品为4开始消费
System.out.println("产品数为4,开始消费");
while (c.productNum>0){
c.productNum--;//消费产品
System.out.println("库存"+c.productNum);
}
System.out.println("产品数"+c.productNum+"生产结束");
c.notify();//唤醒生产者
}else {
try {
c.wait();//消费者线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
},"消费者").start();
}
}
class Clerk{
protected static int productNum=0;
}
无限循环。快乐地完结了全部学习了!未来奥利给!



