Beginners learn Java network programming

  • 2021-10-24 22:50:02
  • OfStack

Directory running thread callback synchronization method synchronization block deadlock priority pause can block to IO can block to synchronization object can give up can sleep can connect to another thread can wait for an object can end can be preempted by higher priority thread summary

Running thread

Create a subclass of Thread


public class ThreadChild extends Thread {
    @Override
    public void run() {
        while (true) {
            System.out.println("run");
        }
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}

Create an Thread incoming Runnable interface implementation class


public class RunnableImpl implements Runnable {
    @Override
    public void run() {
        while (true) {
            System.out.println("run");
        }
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        Thread t = new Thread(new RunnableImpl());
        t.start();
    }
}

Callback

Submit () of ExecutorService thread pool can receive Runnable or Callable. Callable has a return value after execution, but Runnable has no return value after execution. The return value can be obtained by get method of Future of submit. It should be noted that get method is a blocking method. If the thread is not executed, it will block get () until the thread executes and returns data.


public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Future<Integer> future = executorService.submit(() -> {
            TimeUnit.SECONDS.sleep( 3);
            return 1;
        });
        Future<?> future2 = executorService.submit(() -> {
        });
        Future<String> future3 = executorService.submit(() -> {
        }, "aaa");
        System.out.println(future.get());
        System.out.println(future2.get());
        System.out.println(future3.get());
    }

Synchronization method

When the synchronized keyword is combined with the method, the method is a synchronous method. Synchronization methods have one implicit lock. When multiple threads execute this method at the same time, it can only be executed sequentially, and threads that are not strong enough to lock are in blocking state. In addition, static methods and non-static methods use different locks, and the locks of non-static methods are object locks, which do not affect each other if two threads call through two objects of this class. Static methods are class locks, that is, Class objects of this class. The synchronization method cannot specify a lock resource, either an this lock or an Class lock.


public class Test {
    public static void main(String[] args) throws Exception {
        Test test = new Test();
        Thread t1 = new Thread(()->{
            test.synFunction();
        });
        Thread t2 = new Thread(()->{
            test.synFunction();
        });
        t1.start();
        t2.start();
    }
    public synchronized void synFunction(){
        try {
            System.out.println("-------------");
            TimeUnit.SECONDS.sleep(3);
        }catch (Exception e) {}        
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(()->{
            Test.synFunction();
        });
        Thread t2 = new Thread(()->{
            Test.synFunction();
        });
        t1.start();
        t2.start();
    }
    public static synchronized void synFunction(){
        try {
            System.out.println("-------------");
            TimeUnit.SECONDS.sleep(3);
        }catch (Exception e) {}        
    }
}

Synchronization block

Synchronization code blocks can specify lock objects, non-static methods can specify arbitrary object locks, or arbitrary class locks. However, static methods can only use arbitrary class locks.


public class Test {
    public static void main(String[] args) throws Exception {
        Test lock = new Test();
        Thread t1 = new Thread(() -> {
            lock.synFunction();
        });
        Thread t2 = new Thread(() -> {
            lock.synFunction();
        });
        t1.start();
        t2.start();
    }
    public void synFunction() {
        synchronized (this) {// Object lock 
            try {
                System.out.println("-------------");
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
            }
        }
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        Test lock1 = new Test();
        Test lock2 = new Test();
        Thread t1 = new Thread(() -> {
            lock1.synFunction(lock1);
        });
        Thread t2 = new Thread(() -> {
            lock2.synFunction(lock2);
        });
        t1.start();
        t2.start();
    }
    public void synFunction(Object lock) {
        synchronized (lock) {// Object lock 
            try {
                System.out.println("-------------");
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
            }
        }
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        Test lock1 = new Test();
        Test lock2 = new Test();
        Thread t1 = new Thread(() -> {
            lock1.synFunction();
        });
        Thread t2 = new Thread(() -> {
            lock2.synFunction();
        });
        t1.start();
        t2.start();
    }
    public void synFunction() {
        synchronized (Test.class) {// Class lock 
            try {
                System.out.println("-------------");
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
            }
        }
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}
0

Deadlock

When multiple threads compete for locks, deadlocks may result. A thread that blocks because it does not get a lock will not release the acquired lock. Method 1 acquires locks in the order Test. class, Object. class. Method 2 acquires locks in the order of Object. class, Test. class. The program will fall into deadlock.


public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}
1

Priority

Not all threads are created equally, each thread has a priority, specifying an integer from 0 to 10. When multiple threads are running, virtual machines usually run only the threads with the highest priority, but this is not a strict rule. In Java, 10 is the highest priority and 0 is the lowest priority. The default priority is 5. Not all operating systems support these 11 priorities. For example, Windows has only seven priorities. Priorities (1, 2) (3, 4) (6, 7) (8, 9) do the same.


public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}
2

Suspend

In order to give other threads a chance to run, a thread has 8 ways to pause or indicate that it is ready to pause.

IO can be blocked

The most common way for a thread in a network program to automatically relinquish CPU control is IO blocking. Because CPU is much faster than network and disk, network programs often block while waiting for data to arrive from or send data to the network. Even if only a few milliseconds are blocked, this 1 point is enough time for other threads to complete important tasks.

You can block synchronization objects

Threads will also block when entering 1 synchronization method or code block. If the thread does not have a lock on the synchronized object and another thread owns the lock, the thread pauses until the lock is released. If the lock is never released, the thread will stop permanently.

You can give up

The static method Thread. yield () is invoked to give up control of the thread, which notifies the virtual machine that other threads can be executed first. Abandoning does not release the lock held by the thread, so ideally the abandoned thread should not do any synchronization. If other threads waiting to run are blocked because of synchronization resources owned by this thread, these threads will not run. In effect, control will go back to the only thread that can run, that is, the thread that just gave up, which largely loses the meaning of giving up.


public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            Test.synFunction("aaaaaaaaaaa");
        });
        Thread t2 = new Thread(() -> {
            Test.synFunction2("bbbbbbbbbb");
        });
        t1.start();
        t2.start();
    }
    public static void synFunction(String name) {
        for (int i = 0;; i++) {
            Thread.yield();
            System.out.println(name + "--------------" + i);
        }
    }
    public static void synFunction2(String name) {
        for (int i = 0;; i++)
            System.out.println(name + "--------------"+i);
    }
}

Can sleep

Hibernation is a more favorable way to give up. Abandoning simply means that the thread is willing to pause, giving other threads with the same priority a chance to run, while the threads that go to sleep are different, and the dormant threads will pause regardless of whether other threads are ready to run or not. In this way, not only other threads with the same priority will get the opportunity, but also threads with lower priority will be given the opportunity to run. However, the hibernating thread still has all the locks it has acquired. So other threads that require the same lock will still block, avoid putting threads to sleep within synchronization methods or blocks.


public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}
4

public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}
5

You can connect another thread

The connecting thread (the thread A that calls the join () method) waits for the connected thread (join () method to belong to the thread object B) to finish executing before executing. The join () A thread that the A thread calls the B thread waits for the B thread to finish executing before continuing. Note that the A thread does not release the lock resources it has acquired.


public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}
6

You can wait for 1 object

A thread can wait for an object it locks. While waiting, It releases the lock on the object and pauses, Until it is notified by another thread. The other thread modifies this object in some way, Notifies the thread waiting for the object, and then continues execution. Waiting pauses execution until an object or resource reaches a certain state. In fact, to wait for a particular object, the thread wishing to pause must first acquire a lock on the object using synchronized, and then call one of the object's three overloaded wait () methods.


public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}
7

Can end

Threads should give up CPU control in a reasonable way, When the run () method returns to a thread, The thread will undo, Other threads can take over CPU. In network applications, Threads that wrap a blocking operation often do this, For example, a thread downloads a file from the server, So that other parts of the application will not be blocked. Another aspect, If the run () method is too simple, Always end quickly, not violet, and there is a real problem: whether it is necessary to generate a thread. Virtual machines have a lot of overhead when setting up and undoing threads. If threads end in extreme time, using a simple method call instead of a single thread may end faster.

Can be preempted by higher priority threads

Thread setPriority(int priority) Set the priority of threads.

Summarize

This article is here, I hope to give you help, but also hope that you can pay more attention to this site more content!


Related articles: