@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
//获取当前cpu的数量
int i = runtime.availableProcessors();
System.out.println("当前cpu的数量" + i);
}
}
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) {
//创建Cat对象,可以当作线程使用
Cat cat = new Cat();
cat.start();//启动线程
}
}
//1.当一个类继承Thread类,该类就可以当作线程使用
//2.我们会重写run方法,写上自己的业务代码
//3.run Thread 类 实现了Runnable 接口的 run方法
class Cat extends Thread {
@Override
public void run() { //重写run方法,写上自己的业务逻辑
while (true) {
//该线程每隔1秒,在控制台输出“喵喵,我是小猫咪”
System.out.println("喵喵,我是小猫咪" + "当前线程名"+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) {
Cat cat = new Cat();
Thread thread = new Thread(cat);
thread.start();
}
}
class Cat implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("喵喵,我是小猫咪" + "当前线程名"+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
案例:实现多个线程;命令行输入:jconsole查看线程 (建议使用Runnable)
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) {
Thread thread1 = new Thread(new Cat());
Thread thread2 = new Thread(new Dog());
thread1.start();
thread2.start();
}
}
class Cat implements Runnable{
@Override
public void run() {
while (true){
try {
Thread.sleep(1000);
System.out.println("猫");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Dog implements Runnable{
@Override
public void run() {
while (true){
try {
Thread.sleep(1000);
System.out.println("狗");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
案例:创建一个子线程,每隔1秒输出hello,输出20次,主线程每隔1秒,输出hi,输出20次,要求两个线程同时执行,当主线程输出5次后,就让子线程再继续。
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) {
Say say = new Say();
Thread thread = new Thread(say);
thread.start();
for (int i = 0; i < 20; i++) {
if (i == 5){
try {
// Thread.yield(); //主线程让步
thread.join(); //子线程插队
} catch (Exception e) {
e.printStackTrace();
}
}{
try {
Thread.sleep(1000);
System.out.println("hi");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Say implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(1000);
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
1.用户线程:也叫工作线程,当线程的任务的执行完成或通知方法结束
2.守护线程:一般是为工作线程服务的,当所有的用户线程结束,守护线程自动结束
3.常见的守护线程:垃圾回收机制
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) throws InterruptedException {
MyDaemonThread myDaemonThread = new MyDaemonThread();
//如果我们希望当main线程结束后子线程自动结束
//只需将子线程设置为守护线程即可 注意顺序先设置在执行
myDaemonThread.setDaemon(true);
myDaemonThread.start();
for (int i = 0; i < 10; i++) {
System.out.println("hi");
Thread.sleep(1000);
}
}
}
class MyDaemonThread extends Thread{
@Override
public void run() {
for (;;) {
try {
Thread.sleep(1000);
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
1.在多线程编程,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时候,最多有一个线程访问,以保证数据的完整性。2.也可以理解:当一个线程操作内存的时候其他线程不能对该内存进行操作(卖票案例)
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) throws InterruptedException {
SellTickets sellTickets1 = new SellTickets();
SellTickets sellTickets2 = new SellTickets();
SellTickets sellTickets3 = new SellTickets();
Thread thread1 = new Thread(sellTickets1);
Thread thread2 = new Thread(sellTickets2);
Thread thread3 = new Thread(sellTickets3);
thread1.start();
thread2.start();
thread3.start();
}
}
class SellTickets implements Runnable {
public static int tickets = 100;
public static boolean loop = true;
public synchronized void sell() {
System.out.println(Thread.currentThread().getName() + "窗口卖出了一张票剩余" + --tickets);
if (tickets <= 0) {
loop = false;
System.out.println("售空");
}
}
@Override
public void run() {
while (loop) {
sell();
}
}
}
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) throws InterruptedException {
SellTickets sellTickets1 = new SellTickets();
SellTickets sellTickets2 = new SellTickets();
SellTickets sellTickets3 = new SellTickets();
Thread thread1 = new Thread(sellTickets1);
Thread thread2 = new Thread(sellTickets2);
Thread thread3 = new Thread(sellTickets3);
thread1.start();
thread2.start();
thread3.start();
}
}
class SellTickets implements Runnable {
public static int tickets = 100;
public static boolean loop = true;
Object object = new Object();
//同步方法(静态的)的锁为当前·类本身
// public synchronized static void m1(){} 锁是加载在SellTickets.class上
public synchronized static void m1(){
}
//静态方法加载在类上
public static void m2(){
synchronized (SellTickets.class){
}
}
//说明
// public synchronized void sell() {} //就是一个同步方法,这时锁在 this对象
//也可以在代码块上写synchronized,同步代码块,互斥锁还是加载this对象
//同步代码块的对象变为Object,只要是同一个对象就可以
public /*synchronized*/ void sell() {
synchronized (/*this*/ object) {
System.out.println(Thread.currentThread().getName() + "窗口卖出了一张票剩余" + --tickets);
if (tickets <= 0) {
loop = false;
System.out.println("售空");
}
}
}
@Override
public void run() {
while (loop) {
sell();
}
}
}
注意事项和细节:同步方法如果没有使用staic修饰:默认锁对象为this。如果方法使用static修饰,默认对象为当前类.class
实现的落地步骤:需要先分析上锁的代码,选择同步代码块或同步方法,要求多个线程对象为同一个即可
多个线程都占用了对方的锁资源,但不肯相让,导致死锁,在编程是一定要避免死锁的发生
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) throws InterruptedException {
new DeadLockDemo(true).start();
new DeadLockDemo(false).start();
}
}
class DeadLockDemo extends Thread{
static Object object1 = new Object();
static Object object2 = new Object();
boolean flag;
public DeadLockDemo(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
if (flag){
synchronized (object1){
System.out.println(Thread.currentThread().getName()+"进入1");
synchronized (object2){
System.out.println(Thread.currentThread().getName()+"进入2");
}
}
}else{
synchronized (object2){
System.out.println(Thread.currentThread().getName()+"进入3");
synchronized (object1){
System.out.println(Thread.currentThread().getName()+"进入4");
}
}
}
}
}
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) throws InterruptedException {
new PrintNum().start();
new ScannerQ().start();
}
}
class PrintNum extends Thread {
static boolean flg = true;
@Override
public void run() {
while (flg) {
try {
System.out.println("你好");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ScannerQ extends Thread {
Scanner sc = new Scanner(System.in);
@Override
public void run() {
while (true) {
try {
Thread.sleep(5000);
System.out.println("请输入Q退出");
if (sc.next().toUpperCase().charAt(0) == 'Q') {
PrintNum.flg = false;
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@SuppressWarnings({"all"}) //取消文件警告
public class Hello {
public static void main(String[] args) throws InterruptedException {
T t = new T();
Thread thread1 = new Thread(t);
thread1.setName("爸爸");
Thread thread2 = new Thread(t);
thread2.setName("儿子");
thread1.start();
thread2.start();
}
}
//编程取款的线程
//1.因为这里涉及多个线程共享资源,所以我们使用实现Runnable方式
class T implements Runnable{
private int money = 10000;
@Override
public void run() {
while (true){
//1.这里使用synchronized 实现线程的同步
//2.当多个线程执行到这里时,就会去争取 this对象锁
//3.哪个线程夺取(this对象)就会执行synchronized代码块
//4.争取不到的,就blocked,准备夺取到
//5.this是一个非公平锁
synchronized (this){
//判断余额是否足够
if (money<=0){
System.out.println("余额不足");
break;
}
money -= 1000;
System.out.println(Thread.currentThread().getName() + "取出了1000剩余" + money);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}